__iter__ yield

Boris Borcic bborcic at gmail.com
Mon Mar 10 13:51:18 EDT 2008


Paul Hankin wrote:
> On Mar 10, 3:12 am, George Sakkis <george.sak... at gmail.com> wrote:
>> On Mar 9, 7:37 pm, Paul Hankin <paul.han... at gmail.com> wrote:
>>
>>
>>
>>> On Mar 9, 8:58 pm, duccio <d... at tiscali.it> wrote:
>>>> Someone knows if it's possible to make this __iter__ function with just
>>>> one 'yield' intead of two?
>>>> ...
>>>>      def __iter__(self):
>>>>          yield self #1
>>>>          for n in self.childs:
>>>>              for nn in n.__iter__():
>>>>                  yield nn #2
>>> Only one yield and shorter (but not really any simpler):
>>> from itertools import chain
>>> class Node:
>>>     ...
>>>     def __iter__(self):
>>>         for x in chain([self], *self.childs):
>>>             yield x
>> Actually this doesn't need a yield at all:
>>
>> class Node:
>>     ...
>>     def __iter__(self):
>>         return chain([self], *self.childs)
> 
> The two have slightly different behaviours: without the yield, iter is
> called immediately on every node in the tree as the iterators are
> built. With yield, iterators are built lazily, giving better
> behaviour.

generator expressions allow to save on the 'yield' while keeping the lazy 
behavior, with either :

      def __iter__(self):
         return chain([self],(y for x in self.childs for y in x))

or

      def __iter__(self):
         return (y for x in chain([[self]],self.childs) for y in x)

BB




More information about the Python-list mailing list