0

I'm running Python 3.7.3. I have an iterable which I want to group into iterables of up to N items. This is almost the grouper() recipe from itertools, except that I don't want the last group padded. The best I've been able to come up with is:

from itertools import zip_longest

# From https://docs.python.org/3.7/library/itertools.html#itertools-recipes
def grouper(iterable, n):
    args = [iter(iterable)] * n
    for group in zip_longest(*args):
        yield (item for item in group if item)

names = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
for group in grouper(names, 3):
    print(list(group))

which does indeed do what I want:

python group.py 
['a', 'b', 'c']
['d', 'e', 'f']
['g', 'h']

Is there something better/cleaner?

Yeah, I know, this fails if any item is not truthy, but assume that's not a problem.

Roy Smith
  • 2,039
  • 3
  • 20
  • 27
  • 3
    This belongs on [codereview](https://codereview.stackexchange.com/). – orlp Dec 07 '20 at 03:50
  • 3
    Does this answer your question? [What is the most "pythonic" way to iterate over a list in chunks?](https://stackoverflow.com/questions/434287/what-is-the-most-pythonic-way-to-iterate-over-a-list-in-chunks) Note that some answers cover padding and some only work with sequences, but others do what you want, like [this one](https://stackoverflow.com/a/18243990/4518341). – wjandrea Dec 07 '20 at 03:58
  • I would go with what you have if it were me. You can avoid the "truthy" problem by making your test for a value more precise, ie: `yield (item for item in group if item is not None)`. Of course, your items still can't be `None`. - You could even fix that if you needed to, by using the `fillvalue` parameter to `zip_longest`. You'd just have to pick a fill value that you knew would never show up as an item, and modify your test to check for not that value. I've needed to do that in the past, and have used a reference to the function I'm in as the fill value (`grouper` in this case). – CryptoFool Dec 07 '20 at 04:37
  • I believe you are looking something along these lines List=['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'] group_of=3 res = [List[n:n+N] for n in range(0, len(List), group_of)] print(res) **Output:[['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h']]** – Sachin Rajput Dec 07 '20 at 04:40

0 Answers0