2016-08-07 1 views
0
class Node: 
    def __init__(self, value): 
     self._value = value 
     self._children = [] 
    def __repr__(self): 
     return 'Node({!r})'.format(self._value) 
    def add_child(self, node): 
     self._children.append(node) 
    def __iter__(self): 
     return iter(self._children) 
    def depth_first(self): 
     yield self 
     for c in self: 
      yield from c.depth_first() 
if __name__ == '__main__': 
    root = Node(0) 
    child1 = Node(1) 
    child2 = Node(2) 
    root.add_child(child1) 
    root.add_child(child2) 
    child1.add_child(Node(3)) 
    child1.add_child(Node(4)) 
    child2.add_child(Node(5)) 

for a in root.depth_first(): 
    print(a) 
# Outputs Node(0), Node(1), Node(3), Node(4), Node(2), Node(5) 

リストは私たちが反復処理できるオブジェクトだと思ったのですが、どうしてiter()を使うのですか?私はpythonで新しいので、私にはこのように奇妙な外観。iter()を使ってリストを反復可能にするのはなぜですか?

+0

'iter'はリストを反復可能にしません。反復子を返します。 –

答えて

1

self._childrenを返すことはイテレータとして動作しないlistオブジェクトを返し、覚え、イテレータ反復中にアイテムを供給するために__next__方法を実装するため:

>>> next(list()) # doesn't implement a __next__ method 
TypeError: 'list' object is not an iterator 

list Sは反復可能ありますの場合、iterを呼び出すとイテレータが返されるが、list自体はイテレータではないため、これらのイテレータは正しく処理されない上の答えはthis Questionです。 list_iteratorオブジェクトは必須です__next__メソッドを実装し、それを行うことによって、

list().__iter__() 
Out[93]: <list_iterator at 0x7efe7802d748> 

と繰り返し複数回をサポートしています。

Aは__iter__方法は、各時間__iter__が呼び出されたカスタム新しいlist_iteratorオブジェクトを返します示しています。 iterを呼び出して返すだけで、リストイテレータが返され、__next__を実装する手間が省けます。


用としてコメントをアドレッシングなぜfor c in self._children作品、まあ、それは基本的に同じことをやっているので。どのような基本的にループのために起こることです:

it = iter(self._children) # returns the list iterator 
while True: 
    try: 
     i = next(it) 
     <loop body> 
    except StopIteration: 
     break 

意味、iterは、リストオブジェクトに再び呼び出され、next通話用forループで使用されています。

+0

リストオブジェクトを返すことで何を意味するのか分かりませんでしたか? デフ__init __(自己、値): self._value =値 self._children = [] DEF __repr __(自己): リターン「ノード({R iは、このコードをしようとしたとき、それが良く 'クラスノードを働い。})」形式(self._value) DEF add_child(自ノード): self._children.append(ノード) DEF __iter __(自己): 戻りITER(self._children) DEF depth_first(自己): self._childrenのcの を得ます: yield from c.depth_first() ' –

+0

なぜ私が(self._childrenのcのために)変更すると、それはとてもうまくいくのですか? –

0

すべての反復可能オブジェクトは、iter()関数を実装しています。 iter(obj)はobjを呼び出します。 iter()。これは、例のリストオブジェクトを返すのと同じです。

関連する問題