Python 2和Python 3 - map函数在使用三个参数时的差别?

3
以下代码在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,但是否有更优雅的解决方案适用于两个版本?


你能否重写这段代码?或者将该功能放入一个函数中,而不使用不同的结构体? - Joachim Lusiardi
为什么不使用您自己的自定义函数来实现这个目的呢? - mrzrm
1
@JoachimLusiardi 这是一个被广泛使用的代码,所以我想尽量减少更改。 - Nishant
@mrzrm,那么我可以直接使用from past.builtin import map :-) - Nishant
你的实际操作有多少细节与示例匹配?因为 len(list_1) >= len(list_2) and all(list_1) 似乎是解决你所展示的特定问题的更好方法,而不必担心向后兼容版本的 map 或任何其他替代方案(如 itertools.zip_longest)。 - Blckknght
@Blckknght 我觉得我没法改变解决方案。看这个例子:all(map(compare_items, found, expected)),似乎这种行为是真正需要的。 - Nishant
1个回答

2

实际上,使用多个可迭代对象作为参数的map将会对这些可迭代对象进行zip操作,然后使用来自zip的元组作为变长参数调用函数。因此,您可以使用itertools.starmapzip来获得相同的行为:

>>> 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 ...来解决这个问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接