2010-12-14 6 views
0

Iは、辞書の入れ子集合保持collections.defaultdictに由来nesteddictというクラスがあります。私はpython-する操作をnesteddictオブジェクトの全てを変換インスタンスを実行できるようにしたい派生した再帰データ型を基本データ型に変換するにはどうすればよいですか?

import collections 

class nesteddict(collections.defaultdict): 
    """Nested dictionary structure. 

    Based on Stack Overflow question 635483 
    """ 
    def __init__(self): 
     collections.defaultdict.__init__(self, nesteddict) 
     self.locked = False 

をネイティブdictオブジェクト。これを行うには

一つの方法は、メソッドを持つことです。

def todict(self): 
    for (key,val) in self.iteritems(): 
     if isinstance(val,nesteddict): 
      val.todict() 
      self[key] = dict(val) 
    self = dict(self) 

これは、辞書の種類で、すべての内部マッピングオブジェクトを置き換えることに成功しているが、この方法での最後の文は明らかに仕事に行くのではありません。

In [93]: a = pyutils.nesteddict() 

In [94]: a[1][1] = 'a' 

In [95]: a[1][2] = 'b' 

In [96]: a[2][1] = 'c' 

In [97]: a[2][2] = 'd' 

In [98]: print a 
defaultdict(<class 'pyutils.nesteddict'>, {1: defaultdict(<class 'pyutils.nesteddict'>, {1: 'a', 2: 'b'}), 2: defaultdict(<class 'pyutils.nesteddict'>, {1: 'c', 2: 'd'})}) 

In [99]: a.todict() 

In [100]: print a 
defaultdict(<class 'pyutils.nesteddict'>, {1: {1: 'a', 2: 'b'}, 2: {1: 'c', 2: 'd'}}) 

pythonでこれを行う方法があります:ここで

は一例ですか?オブジェクトを別の型に変換するメソッドがありますか?そうでない場合は、これに代わる良い方法は何ですか。実際にはデータ型が大きい可能性があるので、コピーを作成してから戻すことは好ましくないことに注意してください。

ありがとうございます!
ウリ

+3

「私は希望:

def dictify(d): return {k:dictify(v) for k,v in d.items()} if \ isinstance(d,nesteddict) else d 

dictの()の コンストラクタを呼び出すと、255を参照してくださいにキーワード引数 の数を制限するので、むしろdictの()よりも} {使用することをお勧めしますすべてのnesteddictオブジェクトをpython-native dictオブジェクトに変換するインスタンスを操作できるようにしてください。 "なぜですか?すでに 'dict'オブジェクトです。何かを変換する必要はありません。これは 'defaultdict'のサブクラスです**つまり** dict'です。 –

+0

データを読み込んだ後、ロックしたいと思っています。これを実装する1つの方法は、default_factoryメソッドをKeyErrorを発生させる関数にすることです。これは正常に動作するようです。しかし、私はcPickleを使ってこのクラスをシリアライズするのに問題がありました。純粋なdictへの変換は簡単なシリアライゼーション(jsonを含む)を可能にし、辞書を同様の方法で効果的にロックします。 –

+0

@ S.Lott pickleは、純粋な辞書への変換が必要な一般的な理由です。それ以外の場合は、特別な辞書の定義を持たせる必要があります。 'infinite_defaultdict = lambda:defaultdict(infinite_defaultdict)'です。 –

答えて

5

フリー機能として、それを実行し、そしてあなたがそれをしている間、より機能的なスタイルのアプローチを考えてみます。

def undefaulted(x): 
    return dict(
    (k, undefaulted(v)) 
    for (k, v) in x.iteritems() 
) if isinstance(x, nesteddict) else x 

a = undefaulted(a) 
+0

それはとてもいいです。ありがとう! –

+0

将来の訪問者のために:dictの理解を使用するもう1つの答えは、実際には 'dict()'を使うことよりも優れています。 @ Jamieの主張に加えて、それはまた速く、そしてより熟達しています。 –

1

dict(a)はあなたにdefaultdictから派生する任意のオブジェクトからデフォルトの辞書を提供します。つまり、必要な特別なメソッドをオーバーライドしていないと仮定します。

+0

はい、入れ子になった辞書には再帰的には降りません。トップレベルのnesteddictオブジェクトをdictに変換するだけです。 –

+0

yah ..要求の再帰的な部分を完全に忘れてしまった。私の悪い。 – dietbuddha

0

私はあなたのコード内で最初に気づくのは、あなたが変更しているということである(または変数にself変数を追加しようとしています)。その変数はあなたのクラスの現在のインスタンスを指しています。再割り当てした場合、別の値を指しているだけですが、selfが指す以前の値は変更されません。これはPythonの動作方法です。あなたがしなければ、

def anothertodict(self): 
    stuff = dict(self) 
    for (key,val) in stuff.iteritems(): 
     if isinstance(val,nesteddict): 
      stuff[key] = val.anothertodict() 
    return stuff 

その方法:

だから、何をするためにすべきことはちょうどこのような何か...あなたの方法では、変換の結果を返しているprint a.anothertodict()あなたは何をあなたを取得します取得することを期待しています。

PS:どうしてdefaultdictからdictに変換する必要がありますか?

関連する問題