2016-09-13 7 views
3

は、私はほとんどの機能が使用する私のコードの先頭に辞書テンプレートを保存しようとした:入れ子の辞書copy()またはdeepcopy()?

  • 辞書:キー=クライアント名、値= Dictionary2
  • Dictionary2:キー=ユーザー名、値=なし

私はすべてのクライアントとそのユーザーで記入しました。次に、コードの各部分がこの辞書をコピーして、それ自身の出力を生成することができます。目標は、各出力がテンプレートのような "基本"辞書構造を持ち、Noneが変更できるということです。私は以下を使用し、このdictionnaryを使用して、各プロセスのために

process1dict = clientdict 
# processing 1 
output1dict = ... #modified version of original clientdict, the None values have been replaced by dictionaries/lists 

process2dict = clientdict 
# processing 2 
output2dict = ... #same here but could be different 

私が持っている問題はcliendictは、それがプロセスにコピーされるたびに変化することです! 最初のcliendictNoneの値のために、それは各プロセスの後に(もちろんそれぞれの出力に応じて)変更されることに気付きました。

編集:コピーライブラリが見つかりましたが、copy()が私のケースを助けてくれないようです。 deepcopy()を試してみますが、copy()はなぜ機能しませんでしたか?そしてなぜdeepcopy()は?

+1

はい、あなたはdeepcopy行う必要がある - >あなたは 'clientdict'あなたも'のdict(clientdict) 'や' clientdictすることができます修正するとき、それは変更されるので、それなし 'clientdictDNT'はちょうど、同じ基本辞書を指し.copy() ' – TemporalWolf

+1

SOベテランのNed Batchelderによる[Pythonの名前と値に関する事実と神話](http://nedbatchelder.com/text/names.html)を読んでください。 –

+0

deepcopy()を使用しない場合、新しい辞書のメンバーは、ベースディクショナリに埋め込まれている辞書を指します。 deepcopy()は、コピーされている辞書の内部のもののコピーを作成します。 –

答えて

3

辞書やリストのような変更可能なコレクションで作業しているときに、割り当てを実行すると、そのオブジェクトのコピーはデフォルトで作成されません。つまり、ある辞書のbの別の辞書への割り当てabから元のオブジェクトaへの参照を作成します。bを突然変異させると間接的にaも突然変異するようになります。

この基本的な例を参照してください:この問題を修正し、neworig辞書を維持するために

>>> orig = {"a": 1, "b": 2} 
>>> new = orig 
>>> new["a"] = 9 
>>> orig 
{'a': 9, 'b': 2} 
>>> new 
{'a': 9, 'b': 2} 
>>> new is orig 
True 

newに割り当てるdeepcopyorigの時に作る、お互いを参照しないオブジェクトを分離:

>>> import copy 
>>> orig = {"a": 1, "b": 2} 
>>> new = copy.deepcopy(orig) 
>>> new["a"] = 9 
>>> orig 
{'a': 1, 'b': 2} 
>>> new 
{'a': 9, 'b': 2} 
>>> new is orig 
False 

また、上記にリンクされているPythonドキュメントのdr:drは次のとおりです。

Pythonの代入文はオブジェクトをコピーせず、ターゲットとオブジェクトの間にバインディングを作成します。変更可能なアイテムや変更可能なアイテムを含むコレクションの場合、コピーを変更することなく1つのコピーを変更できるようにコピーが必要な場合があります。

+1

多くの場合、ディープコピーは不要で、実際には危険です。 2つのクライアントに属するオブジェクト 'User(" Somebody ")がある場合、おそらくそれらを2つの同等のオブジェクトに分割し、それらを別々に変更したくないでしょう。 'copy.deepcopy'を必要としない場合は、代わりに' dict.copy'を使用することができます。 'orig = {" a ":1、" b ":2}; new = orig.copy() ' –

+1

この場合、私は2つのクライアントに属するUser Nameオブジェクトを持っていません。私が今問題になっているのは、この 'clientdict'辞書がテンプレートとして使用され、プロセスの辞書の残りを埋めるために 'None'の値が空白文字として使用されたということです。私が最初に質問を書いた最後のところにあった 'copy()'を使いこなそうとしたとき、私はそれがうまくいかなかったことを知りました。ありがとうございました – Alex

+1

#アップル。これは深かった;)と役に立つ –

関連する問題