Welcome, guest | Sign In | My Account | Store | Cart

A (mostly) one-liner that cuts an iterable into X sized chunks...

Python, 10 lines
 ``` 1 2 3 4 5 6 7 8 9 10``` ```>>> a,bite = "supercalifragalisticexpialidocious",3 >>> [(a[d:d+bite]) for d in range(len(a)-bite) if d%bite==0] [('s', 'u', 'p'), ('e', 'r', 'c'), ('a', 'l', 'i'), ('f', 'r', 'a'), ('g', 'a', 'l'), ('i', 's', 't'), ('i', 'c', 'e'), ('x', 'p', 'i'), ('a', 'l', 'i'), ('d', 'o', 'c'), ('i', 'o', 'u')] >>> # or on a list >>> b =['sup', 'erc', 'ali', 'fra', 'gal', 'ist', 'ice', 'xpi', 'ali', 'doc', 'iou'] >>> >>> [(b[d:d+bite]) for d in range(len(b)-bite) if d%bite==0] [['sup', 'erc', 'ali'], ['fra', 'gal', 'ist'], ['ice', 'xpi', 'ali']] ```

WARNING: This code truncates the data if the source data is not evenly divisible by the chunksize...

In my case, I knew the data was evenly divisible beforehand, so this was no problem...

If there is an easier way of doing this, please post it.

Steven Bethard 18 years, 10 months ago

Also, you can do this with:

``````zip(*[iter(s)]*bite)
``````

So that your code works like:

``````py> bite = 3
py> a = "supercalifragalisticexpialidocious"
py> b = ['sup', 'erc', 'ali', 'fra', 'gal', 'ist', 'ice', 'xpi', 'ali', 'doc', 'iou']
py> zip(*[iter(a)]*bite)
[('s', 'u', 'p'), ('e', 'r', 'c'), ('a', 'l', 'i'), ('f', 'r', 'a'), ('g', 'a', 'l'), ('i', 's', 't'), ('i', 'c', 'e'), ('x', 'p', 'i'), ('a', 'l', 'i'), ('d', 'o', 'c'), ('i', 'o', 'u')]
py> zip(*[iter(b)]*bite)
[('sup', 'erc', 'ali'), ('fra', 'gal', 'ist'), ('ice', 'xpi', 'ali')]
``````

However, Guido views this as an abuse of the argument parsing machinery.

Arkady Pogostkin 18 years, 9 months ago

This might work better. [a[x:x+bite] for x in range(0,len(a),bite)]

Zoran Isailovski 18 years, 9 months ago

... but it does not cut off the tail if len % bite != 0. If you need it, use

``````[s[x:x+bite] for x in range(0,len(s),bite) if x+bite&lt;=len(s)]
``````
 Created by John Wundes on Thu, 23 Jun 2005 (PSF)

### Required Modules

• (none specified)