2016-06-27 72 views
1

我基本上試圖讓我的頭周圍使用這個基本的代碼的列表理解。我試着通過列表項的值複製列表項:重複列表項的變量次數與列表理解

y = [1, 2, 0, 1] 
x = [] 
for i in y: 
    for j in range(i): 
     x.append(i) 
# Desired output 
>>> [1, 2, 2, 1] 

x = [i for _ in range(i) for i in y] 
# Wrong output 
>>> [1, 2, 0, 1] 

# Right output 
x = [j for j in y for _ in range(j)] 
>>> [1, 2, 2, 1] 

我只是不能似乎得到我的頭左右,爲什麼我得到的第二個例子錯誤的輸出。有人可以解釋這裏有什麼問題。謝謝。

+0

您的第一個理解'[i for _ in range(i)for i in y]'會給執行帶來錯誤(即'name'i'未定義')。在嵌套列表解析中,循環從外部進入。 – Rahul

+1

@Rahul它不會引發錯誤,因爲前面幾行中的for循環會泄漏'i'的值。 – Selcuk

+1

另請參閱http://stackoverflow.com/a/17657966/4014959 –

回答

3

啓發列表範圍內(項)次
項目當列表理解中有多個for循環時,l oops的處理順序與使用「傳統」for循環的順序相同。您的列表comp提供正確的輸出,其循環順序與開始時的代碼相同,使用.append與傳統的for循環。

由於拉胡爾提到的意見,隔離,

x = [i for _ in range(i) for i in y] 

將給予

NameError: name 'i' is not defined 

它不會在這種情況下,因爲i被前面的代碼定義。


相比之下,看看有嵌套列表比較情況:

y = [1, 2, 0, 1] 
x = [[j for j in range(i)] for i in y] 
print(x)  

輸出

[[0], [0, 1], [], [0]] 

這裏,最外層循環是在外部的理解和內循環處於內在的理解中。因此,對於for i in y的每次迭代,我們創建一個新的列表comp,並在該列表comp中循環range(i)

1

正確的理解是:

x = [i for i in y for j in range(i)] 

這給結果你想
項目由該thread

flattened = [val for sublist in list_of_lists for val in sublist] 
-1
x = [j for j in y for i in range(j)] 
+1

此代碼有點令人困惑,因爲它重新使用'y'。另外,在你的代碼中添加一些解釋總是會更好。沒有解釋的僅有代碼的答案是有用的。 –

+0

謝謝@PM 2Ring,代碼更正 –