2017-03-03 3 views
-1

私はOrderedDictから継承するクラスを持っています。私はそのキーではなく、その値を反復できるようにしたい。ディクショナリサブクラスの値を反復する

私は次のコードがうまくいくはずだと思いますが、そうではありません。値 "1"と "2"を出力する代わりに、再帰エラー(コードの下に表示)の何らかの並べ替えを与えます。

from collections import OrderedDict 

class A(OrderedDict): 
    def __init__(self): 
     super(A, self).__init__()  

    def __iter__(self): 
     for value in self.values(): 
      yield value 
     return 

a = A() 
a[1] = "one" 
a[2] = "two" 

for thing in a: 
    print str(thing) 

次のように私が手にエラーがある:

File "T:\***\Test024.py", line 8, in __iter__ 
    for value in self.values(): 
File "C:\Python27\Lib\collections.py", line 111, in values 
    return [self[key] for key in self] 
RuntimeError: maximum recursion depth exceeded while calling a Python object 

上記の例では動作しないのはなぜ?私はfor thing in a.values():のようなループで値を繰り返し処理できることを知っていますが、辞書の場合は.values()を使用するのが矛盾しないようにしたいと思います。私はコードの他の部分で辞書の機能が必要です。

+0

[間違ったコメント] remove 'return' – sangheestyle

+0

これは何がポイントですか? 1つは、値ではなく反復でキーを返すことを期待しています。単に 'a.itervalues()'を使うだけです。 –

+2

@sangheestyleそれは何もしません。 –

答えて

1

あなたはOrderedDict.values反復しdictの上、例外トレースバックに見ることができるように:あなたは__iter__機能をオーバーライドしたので

File "/usr/lib64/python2.7/collections.py", line 123, in values 
return [self[key] for key in self] 

、これは無限ループになります。

これを克服するために、あなたはこのように、たとえば、values関数をオーバーライドする必要があります:

def values(self): 
    return [self[key] for key in OrderedDict.__iter__(self)] 
0

これは非常にハック解決策があるが、元のOrderedDictの実装(/usr/local/lib/python2.7/collections.py:90)あなたが行うことができますを変更することによって、次

from collections import OrderedDict 

class A(OrderedDict): 
    def __init__(self): 
     super(A, self).__init__() 

    def __iter__(self): 
     'od.__iter__() <==> iter(od)' 
     # Traverse the linked list in order. 
     root = self._OrderedDict__root 
     curr = root[1] 
     while curr is not root: 
      yield self[curr[2]] 
      curr = curr[1] 

a = A() 
a[1] = "one" 
a[2] = "two" 

for thing in a: 
    print str(thing) 

実行すると:

$ ./foo.py 
one 
two