Python 2 против Python 3 - Разница в поведении карты с тремя аргументами? - PullRequest
3 голосов
/ 04 марта 2020

Следующий код ведет себя по-разному в Python 2 против Python 3:

all(map(lambda x,y: x, [1, 2], [1, 2, 3]))

Python 2 дает False, тогда как Python 3 дает True. Документация для Python 2 гласит, что она предоставит None, если более короткий список исчерпан, но Python 3 не сделает это.

Я работаю над кодом, который по какой-то причине действительно нуждается в длине. Какой самый чистый способ получить старое поведение? Я знаю, что могу использовать from past.builtin import map as old_map, но есть ли более элегантное решение, которое будет работать в обеих версиях?

1 Ответ

2 голосов
/ 04 марта 2020

По существу, map с несколькими итерациями для аргументов будет zip итерациями, а затем вызывает функцию с кортежами из zip как var-args. Таким образом, вы можете получить то же поведение, используя itertools.starmap и zip:

>>> a = [10, 20]
>>> b = [1, 2, 3]
>>> f = lambda x, y: x
>>> list(map(f, a, b))
[10, 20]
>>> from itertools import starmap
>>> list(starmap(f, zip(a, b)))
[10, 20]

Тогда желаемого поведения можно достичь, заменив zip на itertools.zip_longest:

>>> from itertools import starmap, zip_longest
>>> list(starmap(f, zip_longest(a, b)))
[10, 20, None]

Обе функции из itertools также существуют в Python 2, за исключением того, что вторая называется izip_longest. Вы можете просто import ... as ... обойти это.

...