2009-05-11 17 views
7

私はPythonで2枚のdicts持っていると仮定します。「」同じままですが、「B」と「C」ように、私はdefaultsからデフォルト値を使用してmydictを拡張できるようにしたい別のdictを使ってPython dictに複数のデフォルトを設定する方法はありますか?

mydict = { 'a': 0 } 

defaults = { 
    'a': 5, 
    'b': 10, 
    'c': 15 
} 

を私はdict.setdefault()dict.update()について知っていますが、それぞれが私が欲しいものの半分しかしません - dict.setdefault()で、私は各変数をループする必要がありますdefaults; dict.update()の場合、defaultsは、既存の値をmydictに吹き飛ばします。

これを行うことができるPythonに組み込まれている機能がありますか?そうでない場合、繰り返しこれよりdict.setdefaults()を呼び出すにループを書くよりPython的な方法があります:

for key in defaults.keys(): 
    mydict.setdefault(key, defaults[key]) 

コンテキスト:私はXMLツリーを解析する方法を制御Pythonでいくつかのデータを書いています。各ノード(つまり、各ノードをどのように処理するか)には記述がありますが、私が書き込むデータはむしろスパースであるが、デフォルトで埋めています。サンプルコードは単なる例です...実際のコードは、デフォルトのdictにもっと多くのキーと値のペアを持っています。

(私はこの全体の問題があるが、マイナーな屁理屈が、それは私を悩まれていますので、私は認識していないよ、この操作を行うには良い方法があった場合、私は思っていた実現しています。)

答えて

7

mydictをデフォルトのコピーにすることはできませんでした。そうすれば、mydictはすべての正しい値で始まるでしょうか?

mydict = default.copy() 
+0

ええ、これは私が通常やっていることです。 – Macke

+0

私はこれについて考えましたが、デフォルト全体がかなり非効率的にコピーされませんでした(特にmydictはすべての値が最初に設定されています)。あなたは新しいdictを作成し、別のものからすべての値をコピーし、その場合にはdict全体を再度書き直します。 –

+2

@Daniel Lew:値はコピーされず、参照のみがコピーされます。新しいdictは、メモリ内の同じ値への新しい参照を持ちます。 – nosklo

0
defaults.update(mydict) 
+0

次に、デフォルトを別のノードに適用する方法を教えてください。 –

+0

オリジナルのコピーをどこかに保管してください。 – SilentGhost

+0

最初にディフォルトのディープコピーを作成してから、 – Stephan202

3

あなたがプロセスで新しい辞書を作成する気にしない場合、これはトリックを行いますが:

newdict = dict(defaults) 
newdict.update(mydict) 

newdictはあなたが必要なものが含まれています。

5

あなたは、Pythonのcollections.DefaultDictが動作する。この同じ方法を行うことができます。これまでに掲載

class MultiDefaultDict(dict): 
    def __init__(self, defaults, **kwargs): 
     self.defaults = defaults 
     self.update(kwargs) 
    def __missing__(self, key): 
     return self.defaults[key] 

>>> mydict2 = MultiDefaultDict(defaults, a=0) 
>>> mydict2['a'] 
0 
>>> mydict2['b'] 
10 
>>> mydict2 
{'a': 0} 

他のソリューションは、すべてのデフォルト値を複製します。これは、要求通りにそれらを共有します。 __contains __()、__iter __()、items()、keys()、values()などの他のdictメソッドをオーバーライドしたい場合もあれば、そうでない場合もあります。

+0

+1 'defaultdict'(と' setdefault() ')と違って、欠けているキーや関連するデフォルト値は実際には基礎辞書には追加されない*ことに重点を置く価値があります。どんな場合でも、もちろん、変更することができます... – martineau

0

私は個人的に辞書オブジェクトを追加したいと思います。あなたが最初にオブジェクトを作成しなければならないことを除いて、ほとんどの場合、辞書のように機能します。

class d_dict(dict): 
    'Dictionary object with easy defaults.' 
    def __init__(self,defaults={}): 
     self.setdefault(defaults)   
    def setdefault(self,defaults): 
     for key, value in defaults.iteritems(): 
      if not key in self: 
       dict.__setitem__(self,key,value) 

これは、SetDefault()メソッドをオーバーライドし、1つまたは複数の項目を含む辞書を取ることを除い辞書型とまったく同じ機能を提供します。作成時にデフォルトを設定することができます。

これは単なる個人的な好みです。 dict.setdefault()は、まだ設定されていない項目を設定していることをすべて理解しています。だから、おそらく場所のオプションで最も簡単なのは次のとおりです。

new_dict = default_dict.copy() 
new_dict.update({'a':0}) 

しかし、何度もこの多くを行う場合は、この外の機能を加えるかもしれません。この時点では、ディクショナリにデフォルトを常に追加するのではなく、カスタム辞書オブジェクトを使用するほうが簡単かもしれません。

関連する問題