2016-10-27 66 views
0

因此,我搜索瞭如何用python的一些單元格初始化一個列表。用n個獨立實例初始化列表

我發現這句法

l = [T] * n

確定,但我通過這個得到了大量的疑難雜症-ED,尋找這是創造了一個多小時的bug的原因。 T的實例在某種程度上是鏈接的,就好像這些單元對T的單個實例的引用一樣!

但是這隻適用於一些類型。請參閱:

l1 = [int] * 10 

print l1[0] 
print l1[1] 

l1[0] = 12 

print l1[0] 
print l1[1] 


l2 = [Counter()] * 10 

for key, value in l2[0].items(): 
    print key, value 

for key, value in l2[1].items(): 
    print key, value 

l2[0]["a"] +=1 

for key, value in l2[0].items(): 
    print key, value 

for key, value in l2[1].items(): 
    print key, value 

輸出:

<type 'int'> 
<type 'int'> 
12 
<type 'int'> 
a 1 
a 1 

作爲一個方面的問題:爲什麼是這樣不一致,爲什麼重複的設計存在擺在首位?

那麼,如何在沒有這種奇怪的重複行爲的情況下使用T的號碼進行初始化?

回答

2

使用列表理解:

l = [f() for _ in range(n)] 

這是一個與可變類型一個常見的問題:

>>> l = [[]] * 2 
>>> l[0].append(4) 
>>> l 
[[4], [4]] 

>>> l = [5] * 2 
>>> l[0] += 1 
>>> l 
[6, 5] 
+0

謝謝,這種行爲背後的設計理念是什麼? –

+0

@lotolmencre可變類型在傳遞時不需要複製,只需引用它們即可,也可以修改它們。 (這比這更復雜一些,但你可以閱讀更多關於[這裏](https://docs.python.org/3/reference/datamodel.html))。 –

0

在第一種情況下,你把類型INT的抽象化到每個列表元素。然後你改變了一個這些位置。

在第二種情況下,您將對計數器的引用放入每個列表元素中。然後你改變了計數器,而不是一個單獨的列表元素。你沒有碰到任何參考文獻,只是他們指出的對象。

在第二種情況下,嘗試做你做的相同事情第一:

l2 = [Counter()] * 10 

for key, value in l2[0].items(): 
    print key, value 

for key, value in l2[1].items(): 
    print key, value 

l2[0] = 12 

這是否取消迷惑你?