2016-10-27 24 views
0

そこで、いくつかのセルを使ってリストを初期化する方法を探しました。独立したインスタンスn個でリストを初期化する

私はこの構文

l = [T] * n

ないokたが、私は、このことにより、大規模な落とし穴-EDを持って、これは時間オーバーのために作成されたバグの原因を探しました。 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の数で初期化を行うにはどうすればよいですか?これは、可変タイプと共通の落とし穴だ

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

答えて

2

はリスト内包を使って最初のケースで

>>> 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型の抽象化を置きます。その後、の1つをに変更しました。

2番目のケースでは、カウンタへの参照を各リスト要素に置きます。その後、個々のリスト要素ではなくカウンタを変更しました。参照のどれにも触れていない、単にそれらが指し示すオブジェクトです。

後者の場合は、最初にあなたがやった同じことをやってみてください。

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 

このお国連が、混乱していますか?

関連する問題