2016-07-16 40 views
0

當讀official tutorial,我遇到了這個例子:瞭解列表綜合Python中

>>> vec = [[1,2,3], [4,5,6], [7,8,9]] 
>>> [num for elem in vec for num in elem] 
[1, 2, 3, 4, 5, 6, 7, 8, 9] 

我不明白這一點,所以我做了一些實驗:

>>> [num for elem in vec] 
[9, 9, 9] 
>>> [num for elem in (vec for num in elem)] 
[9, 9, 9] 

而且我甚至現在更困惑了!

所以,我的問題是:我應該以哪種順序閱讀列表理解?


編輯:我敢肯定,我還沒有和值9任何位置定義的變量num

sunqingyaos-MacBook-Air:Documents sunqingyao$ python 
Python 2.7.10 (default, Oct 23 2015, 19:19:21) 
[GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.59.5)] on darwin 
Type "help", "copyright", "credits" or "license" for more information. 
>>> num 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
NameError: name 'num' is not defined 
>>> vec = [[1,2,3], [4,5,6], [7,8,9]] 
>>> [num for elem in vec for num in elem] 
[1, 2, 3, 4, 5, 6, 7, 8, 9] 
>>> [num for elem in vec] 
[9, 9, 9] 
>>> [num for elem in (vec for num in elem)] 
[9, 9, 9] 
>>> 
+0

我也很困惑。 '[num for elem in vec]'應該拋出一個錯誤,因爲'num'沒有被定義。你確定你還沒有在某個地方定義一個帶有「9」值的'num'變量嗎? –

+0

@Rawing是的,我確定。看到我更新的問題 –

回答

4

列表理解的循環讀取由左到右。如果您的列表理解將被寫爲普通循環會是這個樣子:

>>> vec = [[1,2,3], [4,5,6], [7,8,9]] 
>>> l = [] 
>>> for elem in vec: 
...  for num in elem: 
...   l.append(num) 
... 
>>> l 
[1, 2, 3, 4, 5, 6, 7, 8, 9] 

在Python 2列表解析份額內的變量外範圍,使num可以供以後使用:

>>> vec = [[1,2,3], [4,5,6], [7,8,9]] 
>>> [num for elem in vec for num in elem] 
[1, 2, 3, 4, 5, 6, 7, 8, 9] 
>>> num 
9 

需要注意的是關於Python 3的行爲是不同的:

>>> vec = [[1,2,3], [4,5,6], [7,8,9]] 
>>> [num for elem in vec for num in elem] 
[1, 2, 3, 4, 5, 6, 7, 8, 9] 
>>> num 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
NameError: name 'num' is not defined 
2

不用擔心:)。

當您執行列表理解時,num的值爲9,所以下一次迭代vec時。你會得到一個9的清單。

看到這個。

In [1]: vec = [[1,2,3], [4,5,6], [7,8,9]] 
In [2]: [num for elem in vec for num in elem] 
Out[2]: [1, 2, 3, 4, 5, 6, 7, 8, 9] 
In [3]: num 
Out[3]: 9 
In [4]: [num for elem in vec] 
Out[4]: [9, 9, 9] 
+0

所以這實際上是一個錯誤? http://sackoverflow.com/a/4199355/5399734 –

+0

@sunqingyao很好。謝謝你指出,作爲一個錯誤。 –

+1

@sunqingyao不,這不是一個錯誤,在較舊版本的Python中列表解析運行在周圍代碼的範圍內。出於效率原因,故意這樣做。但是很多人抱怨說它已經改爲Python 3.這意味着Python 3列表組件不會「泄漏」,但它們也比Python 2列表組件更慢,並且會消耗更多的RAM。 –

0
list1 = [num for elem in vec for num in elem] 

#is equivalent to: 

list1 = [] 
for elem in vec: 
    for num in elem: 
     list1.append(num) 
+0

其實OP有下一行的問題。不是這個。 –

0

讓我儘量讓答案更清零。 而且順序顯然是從左到右,最右邊的值將被存儲在變量num和elem中。

初始化數據:

vec = [[1,2,3], [4,5,6], [7,8,9]] 
num # Undefined 
elem # Undefined 

步驟-1:線執行後[num for elem in vec for num in elem]

# Now the value of undefined variable will be 
num = 9 # will keep the last value of the loop as per python 2.7 
elem = [7, 8, 9] # Same applies here (as the loop for elem in vec will get executed first followed by for num in elem) 

步驟2:行執行後[num for elem in vec]

# Output: [9, 9, 9] 
# Since num value is 9 and its get repeated 3 times because of vec has 3 elements (three list object in a list, so for loop will run 3 times) 
# Now the variable value would be 
num = 9 # no change 
elem = [7, 8, 9] # The last tuple of variable vec 

步驟3:執行後[num for elem in (vec for num in elem)]

1. In the first/right loop i.e (vec for num in elem) 
    Here the result will be a generator that will have run thrice since length of elem is 3. 
2. Final for loop will iterate over RESULT1 (the result of for loop #1 having length 3) and since the num value is 9. the result will be [9, 9, 9] # num value repeated thrice.