1

辞書を動的に作成し、それを参照辞書に初期化し、辞書内の特定の値を変更する Python コードを作成していました。しかし、予期しない結果が得られるだけでなく、参照辞書も変更されていることがわかりました。私のコード:

tdict={'a':'1','b':'2','c':'3'}
newdict={}
for i in range(5):
  newdict['name'+str(i)]=tdict
  newdict['name'+str(i)]['a']='value'+str(i)
  print 'tdict:  ',tdict
print 'newdict:  ',newdict

そして結果:

tdict:   {'a': 'value0', 'c': '3', 'b': '2'}
tdict:   {'a': 'value1', 'c': '3', 'b': '2'}
tdict:   {'a': 'value2', 'c': '3', 'b': '2'}
tdict:   {'a': 'value3', 'c': '3', 'b': '2'}
tdict:   {'a': 'value4', 'c': '3', 'b': '2'}
newdict:   {'name4': {'a': 'value4', 'c': '3', 'b': '2'}, 'name2': {'a': 'value4', 'c': '3', 'b': '2'}, 'name3': {'a': 'value4', 'c': '3', 'b': '2'}, 'name0': {'a': 'value4', 'c': '3', 'b': '2'}, 'name1': {'a': 'value4', 'c': '3', 'b': '2'}}

一方、「newdict」は次のようになると予想していました。

newdict:   {'name4': {'a': 'value4', 'c': '3', 'b': '2'}, 'name2': {'a': 'value2', 'c': '3', 'b': '2'}, 'name3': {'a': 'value3', 'c': '3', 'b': '2'}, 'name0': {'a': 'value0', 'c': '3', 'b': '2'}, 'name1': {'a': 'value1', 'c': '3', 'b': '2'}}

なぜこれが起こっているのかを理解するのを手伝ってくれる人はいますか? また、値を割り当てていないのに参照辞書 'tdict' が変更されるのはなぜですか?

前もって感謝します

4

2 に答える 2

2

辞書tdictのすべての値に参照を保存しています:newdict

newdict['name'+str(i)]=tdict

次に、次のようにしてのキー'a'を変更tdictします

# newdict['name'+str(i)] is a reference to tdict
newdict['name'+str(i)]['a']='value'+str(i)
# this is equivalent to doing
tdict['a']='value'+str(i)

あなたが望むのはtdict、 newdict 辞書に のコピーを保存することです:

newdict['name'+str(i)]=dict(tdict)

既存のディクショナリをコンストラクタ引数として使用して新しいディクショナリを作成すると、既存のキーに新しい値を割り当てることができる浅いコピーが作成されます。できないこと (または望ましくないこと) は、このディクショナリ内の変更可能な値を変更することです。例:

>>> a={'a': 1, 'b': 2, 'c': [1,2,3]}
>>> b=dict(a)
>>> b['a']=9
>>> a
{'a': 1, 'c': [1, 2, 3], 'b': 2}
>>> b
{'a': 9, 'c': [1, 2, 3], 'b': 2}
>>> b['c'].append(99)
>>> a
{'a': 1, 'c': [1, 2, 3, 99], 'b': 2}
>>> b
{'a': 9, 'c': [1, 2, 3, 99], 'b': 2}

ディクショナリ内の変更可能な値を変更する場合は、ディープ コピーを作成する必要があります。

>>> import copy
>>> a={'a': 1, 'b': 2, 'c': [1,2,3]}
>>> b=copy.deepcopy(a)
>>> b['a']=9
>>> b['c'].append(99)
>>> a
{'a': 1, 'c': [1, 2, 3], 'b': 2}
>>> b
{'a': 9, 'c': [1, 2, 3, 99], 'b': 2}
于 2012-08-21T10:49:04.363 に答える
0

コピーではなく tdict を参照しているだけです。コピーするには、次のいずれかを使用できます

newdict['name'+str(i)] = tdict.copy()

また

newdict['name'+str(i)] = dict(tdict)

それが役に立てば幸い

于 2012-08-21T10:52:06.780 に答える