为什么 past.builtins 地图行为错误?
Why does past.builtins map behave wrongly?
由于 map
中存在一些行为差异(尤其是 Python 2 和 Python - 之间的三个参数),我试图成为 "safe" 通过使用 from past.builtins import map
这样我的功能就完好无损了。但好像不是这样?
这是一个Python 2代码:
map(lambda x: [x], [1, 2])
给出:
[[1], [2]]
这是 Python 3 代码,我希望它以相同的方式运行,但不是:
from past.builtins import map
map(lambda x: [x], [1, 2])
给出:
[1, 2]
令人惊讶的是,新 map
按预期工作:
from builtins import map # Not needed if you didn't evaluate the above code.
list(map(lambda x: [x], [1, 2]))
past.builtins
的 map
有这样的行为的原因吗?这是一个错误吗?
使用源代码 comments.
中提到的 past.builtins
模块获取 Python 2 map
行为似乎存在一些问题
这是 their implementation of map
中的一个错误。这是他们的代码:
def oldmap(func, *iterables):
"""
map(function, sequence[, sequence, ...]) -> list
Return a list of the results of applying the function to the
items of the argument sequence(s). If more than one sequence is
given, the function is called with an argument list consisting of
the corresponding item of each sequence, substituting None for
missing values when not all sequences have the same length. If
the function is None, return a list of the items of the sequence
(or a list of tuples if more than one sequence).
Test cases:
>>> oldmap(None, 'hello world')
['h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd']
>>> oldmap(None, range(4))
[0, 1, 2, 3]
More test cases are in past.tests.test_builtins.
"""
zipped = itertools.zip_longest(*iterables)
l = list(zipped)
if len(l) == 0:
return []
if func is None:
result = l
else:
result = list(starmap(func, l))
# Inspect to see whether it's a simple sequence of tuples
try:
if max([len(item) for item in result]) == 1:
return list(chain.from_iterable(result))
# return list(flatmap(func, result))
except TypeError as e:
# Simple objects like ints have no len()
pass
return result
错误的地方是:
# Inspect to see whether it's a simple sequence of tuples
在他们的实现中,如果可调用 returns 对象列表的 len
为 1,那么它们是 "unpacked" 并返回一个扁平化列表。我不确定这是从哪里来的,因为据我所知,Python 2 没有这样做,即使是元组也是如此:
# Python 2
print(map(lambda x: (x,), [1, 2]))
# [(1,), (2,)]
图书馆代码存储库中似乎有一个 open issue about it,如果你想继续的话。
由于 map
中存在一些行为差异(尤其是 Python 2 和 Python - from past.builtins import map
这样我的功能就完好无损了。但好像不是这样?
这是一个Python 2代码:
map(lambda x: [x], [1, 2])
给出:
[[1], [2]]
这是 Python 3 代码,我希望它以相同的方式运行,但不是:
from past.builtins import map
map(lambda x: [x], [1, 2])
给出:
[1, 2]
令人惊讶的是,新 map
按预期工作:
from builtins import map # Not needed if you didn't evaluate the above code.
list(map(lambda x: [x], [1, 2]))
past.builtins
的 map
有这样的行为的原因吗?这是一个错误吗?
使用源代码 comments.
中提到的past.builtins
模块获取 Python 2 map
行为似乎存在一些问题
这是 their implementation of map
中的一个错误。这是他们的代码:
def oldmap(func, *iterables):
"""
map(function, sequence[, sequence, ...]) -> list
Return a list of the results of applying the function to the
items of the argument sequence(s). If more than one sequence is
given, the function is called with an argument list consisting of
the corresponding item of each sequence, substituting None for
missing values when not all sequences have the same length. If
the function is None, return a list of the items of the sequence
(or a list of tuples if more than one sequence).
Test cases:
>>> oldmap(None, 'hello world')
['h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd']
>>> oldmap(None, range(4))
[0, 1, 2, 3]
More test cases are in past.tests.test_builtins.
"""
zipped = itertools.zip_longest(*iterables)
l = list(zipped)
if len(l) == 0:
return []
if func is None:
result = l
else:
result = list(starmap(func, l))
# Inspect to see whether it's a simple sequence of tuples
try:
if max([len(item) for item in result]) == 1:
return list(chain.from_iterable(result))
# return list(flatmap(func, result))
except TypeError as e:
# Simple objects like ints have no len()
pass
return result
错误的地方是:
# Inspect to see whether it's a simple sequence of tuples
在他们的实现中,如果可调用 returns 对象列表的 len
为 1,那么它们是 "unpacked" 并返回一个扁平化列表。我不确定这是从哪里来的,因为据我所知,Python 2 没有这样做,即使是元组也是如此:
# Python 2
print(map(lambda x: (x,), [1, 2]))
# [(1,), (2,)]
图书馆代码存储库中似乎有一个 open issue about it,如果你想继续的话。