4

私のコードはもっと明確になると思います-

someList = list()
foo = {'a':'b'}
someList.append(foo)
print someList
>>> [{'a':'b'}]
defaultbazz = {'a':2, 'b':'t', 'c':'gg'}

for k, v in defaultbazz.iteritems():
    foo[k] = v

print someList
>>> [{'a': 2, 'c': 'gg', 'b': 't'}]

最後のプリントはすべきではありません[{'a':'b'}]か?更新していませんがsomeList、そのまま欲しいです。

それは私には解釈されていない振る舞いのようです。

しかし、それがPythonの動作方法である場合、回避策を見つけるにはどうすればよいですか?新しいdictを設定しても、元のdictが更新されます。つまり、次のようになります。

someList = list()
foo = {'a':'b'}
someList.append(foo)
print someList
>>> [{'a':'b'}]
bar = foo
defaultbazz = {'a':2, 'b':'t', 'c':'gg'}

for k, v in defaultbazz.iteritems():
    bar[k] = v

print someList
>>> [{'a': 2, 'c': 'gg', 'b': 't'}]

なぜそれが起こるのか誰かが私に説明してくれるなら、私は感謝するでしょう。

4

5 に答える 5

11

辞書をリストに追加したり、新しい変数に割り当てたりすると、辞書がコピーされることを期待しているように見えますが、それは Python の動作ではありません。dict を割り当てる場合 (実際には、任意のオブジェクトを割り当てる場合)、新しいオブジェクトを作成するのではなく、オブジェクトに新しい名前を付けるだけです。(オブジェクトは複数の名前を持つことができます。)

したがって、新しい名前でオブジェクトを編集すると、そのオブジェクトの単一のインスタンスが変更され、その変更は、任意の名前でオブジェクトにアクセスしたときに表示されます。

オブジェクトをコピーする場合は、次のようにします。

bar = dict(foo)

また

bar = foo.copy()
于 2012-07-22T14:00:16.150 に答える
5

単純化するには:

a = {2: 3}
b = [a]

bへの「参照」が含まれていますa(そして はdict可変です) - したがって、が変更された場合、 list を介してaアクセスすると、変更された が表示されます。aba

のコピーを明示的に作成する必要がありますa。この場合、次のように実行できます。

b = [dict(a)]

ただし、copyモジュールと forcopy.copy()を確認する必要がありますcopy.deepcopy()

于 2012-07-22T13:59:29.990 に答える
3

辞書は変更可能なオブジェクトであるため、スクリプトの結果です。新しいオブジェクト、つまり元のオブジェクトのコピーが必要だと思います。

import copy

someList.append(copy.copy(foo))
于 2012-07-22T13:58:56.260 に答える
2

Python の変数は、単なるオブジェクトの名前です。オブジェクトに「付けられた」任意の名前を変更すると、他のすべての名前からの変更が表示されます。Python が自動的にコピーを作成することはありません。特に:

someList.append(foo)

のコピーを作成してfoo配置するのではなく、名前が参照するオブジェクトをリストsomeListに追加します。 foo

このオブジェクトの 2 番目の名前を作成できます

bar = foo

しかし、これもコピーを作成しません。特に

foo['x'] = 42

bar['x'] = 42

その後、まったく同じオブジェクトで動作します。これは、オブジェクトのメモリ アドレスを出力することで確認できます。

print id(foo), id(bar)

そして、それらが同じであることを確認してください。

Python でコピーが必要な場合は、明示的に作成する必要があります。必要なものに応じて、copyモジュール --copy.copy()またはcopy.deepcopy()-- はあなたが望むことを行います:

import copy
bar = copy.copy(foo)
print id(foo), id(bar)

異なるメモリの場所を出力するはずです。

于 2012-07-22T14:06:23.447 に答える
1

辞書はミュータブルです。つまり、変更することができます。fooが の中にありsomeList、 で変更fooしているためですfor-loop。次の簡単な例を見てください。

a_dict = {'a':'b'}
a_list = [a_dict]
print a_list # [{'a':'b'}]

#change the dict
a_dict['a'] = 'c'
print a_list # [{'a':'c'}]
于 2012-07-22T13:58:12.903 に答える