Simple List division problem
thebjorn
BjornSteinarFjeldPettersen at gmail.com
Sun Jan 13 07:55:04 EST 2008
On Jan 13, 1:05 pm, thebjorn <BjornSteinarFjeldPetter... at gmail.com>
wrote:
> On Jan 12, 8:33 pm, Fredrik Lundh <fred... at pythonware.com> wrote:
>
>
>
> > marcstuart wrote:
> > > How do I divide a list into a set group of sublist's- if the list is
> > > not evenly dividable ? consider this example:
>
> > > x = [1,2,3,4,5,6,7,8,9,10]
> > > y = 3 # number of lists I want to break x into
> > > z = y/x
>
> > > what I would like to get is 3 sublists
>
> > > print z[0] = [1,2,3]
> > > print z[2] = [4,5,6]
> > > print z[3] = [7,8,9,10]
>
> > > obviously not even, one list will have 4 elements, the other 2 will
> > > have 3.,
>
> > here's one way to do it:
>
> > # chop it up
> > n = len(x) / y
> > z = [x[i:i+n] for i in xrange(0, len(x), n)]
>
> > # if the last piece is too short, add it to one before it
> > if len(z[-1]) < n and len(z) > 1:
> > z[-2].extend(z.pop(-1))
>
> > </F>
>
> Eh...
>
> def chop(lst, length):
> n = len(lst) / length
> z = [lst[i:i+n] for i in xrange(0, len(lst), n)]
> if len(z[-1]) < n and len(z) > 1:
> z[-2].extend(z.pop(-1))
> return z
>
> gives
>
> >>> chop(range(1,9), 3)
>
> [[1, 2], [3, 4], [5, 6], [7, 8]]>>> chop(range(1,8), 3)
>
> [[1, 2], [3, 4], [5, 6, 7]]>>> chop(range(1,6), 3)
>
> [[1], [2], [3], [4], [5]]>>> chop([1], 3)
>
> Traceback (most recent call last):
> File "<stdin>", line 1, in <module>
> File "beforemeth.py", line 9, in chop
> if len(z[-1]) < n and len(z) > 1:
> ValueError: xrange() arg 3 must not be zero
>
> Perhaps something like this?
>
> def chop(lst, length):
> from itertools import islice
> it = iter(lst)
> z = [list(islice(it, length)) for i in xrange(1 + len(lst) //
> length)]
> if len(z) > 1:
> z[-2].extend(z.pop()) # the last item will be empty or contain
> "overflow" elements.
> return z
>
> -- bjorn
Bad for to reply to myself, I know, but I just realized that the OP
wanted to control the _number_ of chunks, not the size of the
chunks... Building on the above would give something like
from itertools import islice
from operator import add
def chop(lst, nchunks):
chunksize, extra = divmod(len(lst), nchunks)
if not chunksize:
raise ValueError('More chunks than elements in list.')
it = iter(lst)
z = [list(islice(it, chunksize)) for i in xrange(nchunks + extra)]
z, extra = z[:nchunks], z[nchunks:]
z[-1].extend(reduce(add, extra, [])) # because sum ain't add :-(
return z
-- bjorn
More information about the Python-list
mailing list