[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Accumulator

"Fredrik Lundh" <fredrik@pythonware.com> writes:

> alexander wrote:
> ...
> > Zip is easily the python function I like best (for one thing, because it
> > allows elegant uses of infinite sequences), so I would be even willing to
> > sacrifice map if it would bring more people closer to the wonders of zip :)
> footnote: zip(...) is of course the same thing as map(None, ...)
> with a different stop condition in case the lengths differ.

Ahh, but the difference is essential, because it allows you use sequences that
are conceptually infinite. Just a boring example:

>>> INFI = xrange(sys.maxint) # creates lazy list [0,...,sys.maxint)
>>> l = ["foo", "bar", "quux", "..."]
>>> d = dict(zip(INFI, l))    # converts list of pairs to hash keys and values
>>> l[1]
>>> d[1]
>>> d = dict(map(None, INFI, l))
Traceback (most recent call last):
  File "<stdin>", line 1, in ?

Since python unfortunately hasn't got a set type (yet), you'd likely more
often use this with `l` and `INFI` interchanged to quickly create a poor man's

Because zip's stopping behavior is so useful, I also defined a function
xzipWith, which is a lazy version of map with zips stop criterion and looks
like this:

def xzipWith(func, *seqs):
    itrs = map(iter, seqs) # makes sure everything is an iterator
    while 1: yield func(*[itr.next() for itr in itrs])

Indeed, I almost never find the None padding behavior useful, so if it weren't
for the fact that map is shorter to type, a builtin and therefore faster and
familiar to all pythonistas, I would always stick with (x)zipWith.

Plus I always considered `None` as first argument to map and filter as a hack
-- (for filter it seems completely superfluous by now as using operator.truth
/ bool for is both clearer and (with 2.2.1+'s bool) even less typing).

> def zip(*args):
>     return fancymap(STOP, None, *args)
> def map(func, *args):
>     return fancymap(PAD_WITH_NONE, func, *args)
> </F>