python - 为什么过去的内置 map 行为错误?

标签 python python-3.x python-2.x migrating

由于 map 中存在一些行为差异(尤其是 Python 2 和 Python - Python 2 vs Python 3 - Difference in map behavior with three arguments? 之间的三个参数),因此我试图通过使用过去的 来“安全”。内置导入 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.builtinsmap 的行为有这样的原因吗?这是一个错误吗?


如源代码 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

在它们的实现中,如果可调用返回一个 len 为 1 的对象列表,那么这些对象将被“解包”并返回一个扁平列表。但我不确定这是从哪里来的,因为据我所知,Python 2 没有这样做,即使对于元组也是如此:

# Python 2
print(map(lambda x: (x,), [1, 2]))
# [(1,), (2,)]

似乎有一个 open issue about it如果您想继续关注,请在库代码存储库中查看。

关于python - 为什么过去的内置 map 行为错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60654635/

相关文章:

python - 列表推导中的 Lambda 在调用时返回一个 lambda

linux - Python 找不到 mongoengine 模块

python - Python cv2.imread返回 'NoneType'对象没有属性 'shape'

python - 是否可以保证这将是一个生成器?

python - 如果找不到 item 中的字母之一,我该如何循环它来执行 driver.refresh() 并重试?

python - 如何检查可迭代对象是否允许多次通过?

multithreading - python的queue.Queue.put()方法是异步的吗?

带有数据库的 Python 消费者应用程序

python - 为什么列表和元组会改变枚举的输出?

python - 如何查找所有 Python 内置私有(private)变量,如 __file__、__name__