2016-08-17 13 views
1

私はこのようなネストされた辞書を持っていますが、はるかに大きい:入れ子の辞書にdeepcopyを使用する代わりに?

d = {'a': {'b': 'c'}, 'd': {'e': {'f':2}}} 

私は、入力として辞書やキーのパスを受け取り、そのパスに関連付けられた値を返す関数を書きました。

>>> p = 'd/e' 
>>> get_from_path(d, p) 
>>> {'f':2} 

ネストされた辞書を取得したら、それを変更する必要がありますが、dは変更できません。ディープコピーを使用する必要がありますか、または辞書を常にコピーする必要がない、より効率的なソリューションがありますか?

+0

あなたの反対意見は効率だけに基づいてディープコピーになっていますか?これは問題の原因となるコードのパフォーマンスにとって重要な部分ですか? – SethMMorton

+0

ネストされた辞書を見つけたら、それを一度ディープコピーする必要があります。したがって、「辞書のコピーを常に作成する」ことが何を意味するのかは分かりません。 – Karin

+0

@SethMMortonまったくありません。明らかに、より効率的なソリューションが常に優れていますが、私の主な反対は、私がコピーモジュールをインポートする必要がないということです。 – Bretsky

答えて

1

あなたのユースケースに応じて、既存の辞書に変更を加えることを避けるための一つのアプローチは、collections.ChainMapでそれをラップすることです:

>>> import collections 

>>> # here's a dictionary we want to avoid dirty'ing 
>>> d = {i: i for in in range(10)} 

>>> # wrap into a chain map and make changes there 
>>> c = collections.ChainMap({}, d) 

今、私たちは中に起こって、対応する変更を加えることなくcに新しいキーと値を追加することができますこのソリューションが適切であるかどうかd

>>> c[0] = -100 
>>> print(c[0], d[0]) 
-100 0 

特に...あなたのユースケースに依存ChainMapは以下となります。

それはいくつかのものに来るとき
  • は、キーを削除するように、通常のマップのように動作しません:

    >>> del c[0] 
    >>> print(c[0]) 
    0 
    
  • はまだ

    >>> d = dict(a=[]) 
    >>> collections.ChainMap({}, d)["a"].append(1) 
    

    あなたの場所に値を変更できるようにリストを変更しますd

ただし、あなたの埋め込まれた辞書を取って、いくつかの新しいキーと値をポップすると、ChainMapが適切かもしれません。

+0

この縮尺はどのようにネストされた辞書(OPが尋ねたもの)になりますか? – martineau

+0

これは浅い辞書を作るのと同じようです。'd'にリストのような変更可能な属性がある場合、' c'でリストを変更すると、 'd'でそれを変更します。 – Karin

+0

これはc = copy.deepcoy(d)とどう違うのですか? –

関連する問題