Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I get Python2.x `map` functionality in Python3.x?

Tags:

python-3.x

The signature for map is

map(function, iterable[, iterables[, ...]])

In Python 2.x if function is None identity is assumed, and short iterables are padded with 'None' to the length of the longest iterable.

In Python 3.x if function is None you eventually get an exception:

TypeError: 'NoneType' object is not callable

and all iterables are trimmed to the length of the shortest one.

That's a couple of pretty drastic changes. How do I get 2.x semantics back?

Oh, and it now returns an iterator instead of a list, but I'm okay with that change. ;)


This is useful for cases where you don't know ahead of time which function, if any, will be applied -- just because you aren't actually transforming the iterable doesn't mean you don't want its contents.

like image 874
Ethan Furman Avatar asked May 12 '26 11:05

Ethan Furman


1 Answers

You must roll your own -- but it's easy:

from itertools import zip_longest, starmap

def map2x(func, *iterables):
    if len(iterables) == 1:
        zipped = list(iterables[0])
    else:
        zipped = zip_longest(*iterables)
    if func is None:
        return zipped
    return starmap(func, zipped)

A simple example:

a=['a1']
b=['b1','b2','b3']
c=['c1','c2']

print(list(map2x(None, a, b, c)))

which gives us:

[('a1', 'b1', 'c1'), (None, 'b2', 'c2'), (None, 'b3', None)]

If you have only one iterable, like:

map(None, 'hello world')

Then simply replace that with:

list('hello world')

Update:

My original answer here didn't work if you called map() with None as function and only one iterable. That's because nobody does that, since then you can just as well just use list(iterable). But I added the handling of that case anyway, by popular request. :-)

like image 105
Lennart Regebro Avatar answered May 14 '26 11:05

Lennart Regebro



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!