2014-07-10 128 views
7

我正在處理列表和訪問列的列表一直很混亂。爲什麼x [i] [:] = x [:] [i]其中x是列表的列表?

假設x被定義如下:

x = [[int(np.random.rand()*100) for i in xrange(5)] for x in xrange(10)] 
    pprint.pprint(x) 
[[86, 92, 95, 78, 68], 
[76, 80, 44, 30, 73], 
[48, 85, 99, 35, 14], 
[3, 84, 50, 39, 47], 
[3, 7, 67, 28, 65], 
[19, 13, 98, 53, 33], 
[9, 97, 35, 25, 89], 
[48, 3, 48, 5, 1], 
[21, 40, 72, 61, 62], 
[58, 43, 84, 69, 26]] 

現在,無論x[1][:]x[:][1]產生相同的結果:

[76, 80, 44, 30, 73] 

有人能解釋一下爲什麼? 謝謝

+2

你爲什麼使用列表清單?你有NumPy!你正在使用NumPy的隨機數發生器!使用數組!如果你有一個數組而不是列表列表,'x [i,:]'和'x [:,i]'會做你想要的。 – user2357112

+0

因爲我有不同大小和類型的列表,這裏的示例僅用於說明。 – ipluto

回答

6

如果將每個表達式的兩個索引操作分解爲單獨的部分,則該行爲非常易於理解。

  • x[1]將是您的列表清單(列表[76, 80, 44, 30, 73])中的第二個值。
  • x[1][:]x[1](跨越整個列表的切片)的副本。
  • x[:]x(列表清單)的(淺)副本。
  • x[:][1]是列表複製列表中的第二個值,與x[1]相同。

因此,這兩個表達式是相等的。請注意,由於第一個表達式複製列表(最後使用[:]切片),它們不是同一個對象(x[1][:] is x[:][1]將是False)。

如果您使用的是2D numpy的數組,你會得到不同的行爲,因爲你可以在任意尺寸(使用稍微不同的語法)切片:

import numpy as np 

x = np.array([[86, 92, 95, 78, 68], 
       [76, 80, 44, 30, 73], 
       [48, 85, 99, 35, 14], 
       [3, 84, 50, 39, 47], 
       [3, 7, 67, 28, 65], 
       [19, 13, 98, 53, 33], 
       [9, 97, 35, 25, 89], 
       [48, 3, 48, 5, 1], 
       [21, 40, 72, 61, 62], 
       [58, 43, 84, 69, 26]]) 

print(x[1,:]) # prints the values of the second row: [76 80 44 30 73] 
print(x[:,1]) # prints the values of the second column: [92 80 85 84 7 13 97 3 40 43] 

這可能是你所期待的。

+0

感謝您的詳細解釋。如果不是我在原始列表中列出的不同類型的列表,我肯定會使用np.array。 – ipluto

3

x[:][1]是整個陣列行1和x[1][:]都是x的第1行,所以他們都指向同一行。

In [2]: x[:] 
Out[2]: 
[[86, 92, 95, 78, 68], 
[76, 80, 44, 30, 73], 
[48, 85, 99, 35, 14], 
[3, 84, 50, 39, 47], 
[3, 7, 67, 28, 65], 
[19, 13, 98, 53, 33], 
[9, 97, 35, 25, 89], 
[48, 3, 48, 5, 1], 
[21, 40, 72, 61, 62], 
[58, 43, 84, 69, 26]] 
In [3]: x[1] 
Out[3]: [76, 80, 44, 30, 73] 

In [4]: x[1][:] 
Out[4]: [76, 80, 44, 30, 73] 

使用x[:]經常使用,如果你想的x的副本保存在一個變量,只是一個參考吧:

In [6]: x1 = x[:] 

In [7]: x1 
Out[7]: 
[[86, 92, 95, 78, 68], 
[76, 80, 44, 30, 73], 
[48, 85, 99, 35, 14], 
[3, 84, 50, 39, 47], 
[3, 7, 67, 28, 65], 
[19, 13, 98, 53, 33], 
[9, 97, 35, 25, 89], 
[48, 3, 48, 5, 1], 
[21, 40, 72, 61, 62], 
[58, 43, 84, 69, 26]] 

創建一個副本:

In [11]: x1 = x[:] 
In [12]: id(x1)  # different objects so different id's 
Out[12]: 140130415845104  
In [13]: id(x) 
Out[13]: 140130400510176 

創建參考:

In [14]: x1 = x 

In [15]: id(x) # same object so same id's 
Out[15]: 140130400510176 

In [16]: id(x1) 
Out[16]: 140130400510176 
1

x[1][:]首先得到x[1]這是列表中的第一個對象。在這種情況下,它是一個列表。然後,通過將[:]添加到該表中,您說要返回該第一個列表中的所有列表對象。所以它從列表的主要列表中返回整個第一個列表對象。

x[:][1]首先說的是x[:]返回整個列表。然後通過添加[1]您只是說要返回整個列表中的第一項。

相關問題