itertools.izip brokeness

Michael Spencer mahs at telcopartners.com
Thu Jan 5 21:59:18 EST 2006


> Bengt Richter wrote:
...
>>  >>> from itertools import repeat, chain, izip
>>  >>> it = iter(lambda z=izip(chain([3,5,8],repeat("Bye")), chain([11,22],repeat("Bye"))):z.next(), ("Bye","Bye"))
>>  >>> for t in it: print t
>>  ...
>>  (3, 11)
>>  (5, 22)
>>  (8, 'Bye')
>>
>> (Feel free to generalize ;-)
> 

rurpy at yahoo.com wrote:
> Is the above code as obvious as
>   izip([3,5,8],[11,22],sentinal='Bye')?
> (where the sentinal keyword causes izip to iterate
> to the longest argument.)
> 

How about:

from itertools import repeat

def izip2(*iterables, **kw):
     """kw:fill. An element that will pad the shorter iterable"""
     fill = repeat(kw.get("fill"))
     iterables = map(iter, iterables)
     iters = range(len(iterables))

     for i in range(10):
         result = []
         for idx in iters:
             try:
                 result.append(iterables[idx].next())
             except StopIteration:
                 iterables[idx] = fill
                 if iterables.count(fill) == len(iterables):
                     raise
                 result.append(fill.next())
         yield tuple(result)

  >>> list(izip2(range(5), range(3), range(8), range(2)))
  [(0, 0, 0, 0), (1, 1, 1, 1), (2, 2, 2, None), (3, None, 3, None), (4, None, 4, 
None), (None, None, 5, None), (None, None, 6, None), (None, None, 7, None)]
  >>> list(izip2(range(5), range(3), range(8), range(2), fill="Empty"))
  [(0, 0, 0, 0), (1, 1, 1, 1), (2, 2, 2, 'Empty'), (3, 'Empty', 3, 'Empty'), (4, 
'Empty', 4, 'Empty'), ('Empty', 'Empty', 5, 'Empty'), ('Empty', 'Empty', 6, 
'Empty'), ('Empty', 'Empty', 7, 'Empty')]
  >>>

Michael





More information about the Python-list mailing list