[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]
'bar'
>>> d[1]
'bar'
>>> d = dict(map(None, INFI, l))
Traceback (most recent call last):
File "<stdin>", line 1, in ?
MemoryError
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
set.
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>
alex