getting n items at a time from a generator

Shane Geiger sgeiger at ncee.net
Thu Dec 27 10:43:13 EST 2007


# http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/496958

from itertools import *
def group(lst, n):
    """group([0,3,4,10,2,3], 2) => iterator

    Group an iterable into an n-tuples iterable. Incomplete tuples
    are padded with Nones e.g.

    >>> list(group(range(10), 3))
    [(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, None, None)]
    """
    iters = tee(lst, n)
    iters = [iters[0]] + [chain(iter, repeat(None))
                 for iter in iters[1:]]
    return izip(
         *[islice(iter, i, None, n) for i, iter
              in enumerate(iters)])

import string
for grp in list(group(string.letters,25)):
   print grp

"""
('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y')
('z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X')
('Y', 'Z', None, None, None, None, None, None, None, None, None, None,
None, None, None, None, None, None, None, None, None, None, None, None,
None)

"""




Kugutsumen wrote:
> On Dec 27, 7:24 pm, Terry Jones <te... at jon.es> wrote:
>   
>>>>>>> "Kugutsumen" == Kugutsumen  <kugutsu... at gmail.com> writes:
>>>>>>>               
>> Kugutsumen> On Dec 27, 7:07 pm, Paul Hankin <paul.han... at gmail.com> wrote:
>>
>>     
>>>> On Dec 27, 11:34 am, Kugutsumen <kugutsu... at gmail.com> wrote:
>>>>         
>>>>> I am relatively new the python language and I am afraid to be missing
>>>>> some clever construct or built-in way equivalent to my 'chunk'
>>>>> generator below.
>>>>>           
>> Kugutsumen> Thanks, I am going to take a look at itertools.  I prefer the
>> Kugutsumen> list version since I need to buffer that chunk in memory at
>> Kugutsumen> this point.
>>
>> Also consider this solution from O'Reilly's Python Cookbook (2nd Ed.) p705
>>
>>     def chop(iterable, length=2):
>>         return izip(*(iter(iterable),) * length)
>>
>> Terry
>>     
>
>   
>> [snip code]
>>
>> Try this instead:
>>
>> import itertools
>>
>> def chunk(iterator, size):
>>     # I prefer the argument order to be the reverse of yours.
>>     while True:
>>         chunk = list(itertools.islice(iterator, size))
>>         if chunk: yield chunk
>>         else: break
>>
>>     
>
> Steven, I really like your version since I've managed to understand it
> in one pass.
> Paul's version works but is too obscure to read for me :)
>
> Thanks a lot again.
>
>
>   


-- 
Shane Geiger
IT Director
National Council on Economic Education
sgeiger at ncee.net  |  402-438-8958  |  http://www.ncee.net

Leading the Campaign for Economic and Financial Literacy




More information about the Python-list mailing list