Re: [Python-Dev] Proposal: new list function: pack
![](https://secure.gravatar.com/avatar/6ee1cd2bb8ac112ee92c6ca716333b36.jpg?s=120&d=mm&r=g)
Isaac Morland wrote:
I propose this because i need a lot of times pack and slide function over list and this one combine the two in a generator way.
I've written functions with a subset of this functionality on more than one occasion. Having it in itertools looks like it would be useful to a lot of people.
See the Python documentation for zip():
zip can be used to achieve this purpose, but only with serious itertools-fu. If I want to iterate over a list [1, 2, 3, 4] looking at pairs (1, 2) and (3, 4), it would be much nicer to write: for a, b in itertools.pack(l, 2): ... than for a, b in itertools.izip(*[iter(l)]*2): ... which is what the zip documentation proposes. The former would be clear to anyone looking at the documentation of "pack" (and maybe even without it if we choose a better name), while the latter requires quite some deciphering, followed by carefully looking at izip's documentation that it's actually legal to rely on argument evaluation order and not peeking at iterables, like that code does. izip is not the only contender for this pattern; something similar is possible using groupby, but it's hard to make it fit in an easily understable line either. This is the shortest I came up with: def pack(iterable, n): cycler = (i for i in itertools.count() for j in xrange(n)) return (g for k, g in itertools.groupby(iterable, lambda x: cycler.next())) This has the nice property that it returns iterables rather than tuples, although tuples are probably good enough (they seem to be good enough for izip). The name "pack" is a bit too cryptic, even by itertools standards, so it might be better to choose a name that conveys the intention of returning "groups of n adjacent elements" (group_adjacent?). To fit with the rest of itertools, and to be really useful, the function shouldn't insist on sequences, but should accept any iterable.
http://drj11.wordpress.com/2009/01/28/my-python-dream-about-groups/
That posting ends with: """ It still scares me a bit. This code is obviously ridiculous. I can’t help feeling I’ve missed a more Pythonic way of doing it. """ Looking at izip(*[iter(l)]*n), I tend to agree.
![](https://secure.gravatar.com/avatar/f3ba3ecffd20251d73749afbfa636786.jpg?s=120&d=mm&r=g)
Hrvoje Niksic wrote:
Looking at izip(*[iter(l)]*n), I tend to agree.
Note that the itertools recipes page in the docs includes the following: def pairwise(iterable): "s -> (s0,s1), (s1,s2), (s2, s3), ..." a, b = tee(iterable) next(b, None) return izip(a, b) There are a couple of other variants here: http://code.activestate.com/recipes/439095/ And a different take on providing similar functionality here: http://code.activestate.com/recipes/544296/ However, the idea of providing a general windowing function in itertools has been considered in the past and emphatically rejected: http://mail.python.org/pipermail/python-dev/2006-May/065305.html Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia ---------------------------------------------------------------
participants (2)
-
Hrvoje Niksic
-
Nick Coghlan