【问题标题】:How to use Python3 map correctly?如何正确使用 Python3 地图?
【发布时间】:2014-12-07 00:24:33
【问题描述】:

对于一些数据,例如:

foo = list()
foo.append( ["a", "b", "c"] )
foo.append( ["d", "e", "f"] )
foo.append( ["g", "h", "i"] )

我可以在 Python 2 中使用 map(shuffle, foo) 来打乱 foo 的每个子列表并从 map 中取回一个列表。

Python 3 中,map(与许多其他方法一样)返回一个对象,在这种情况下,一个 map 对象包含一些带有值的迭代器(至少这是我的想法)。

所以我尝试了一个列表理解:

[ element for element in map(shuffle, foo) ]

还有列表构造函数:

list( map(shuffle, foo) )

还有一个简单的for循环:

for element in map(shuffle, foo)

但我总是得到这些东西

[None, None, None]

我不明白为什么?有人可以帮我解决这个问题吗?

除此之外,还有一件奇怪的事:

# simply calling map
map( shuffle, foo ) # <-- does nothing, foo's elements remain in the same order

# saving the output
someThing = map( shuffle, foo ) # <-- foo's elements are shuffled

为什么第一件事不洗牌 foo 的元素,而第二件事呢?

【问题讨论】:

    标签: python-2.7 python-3.x map shuffle


    【解决方案1】:

    根据the docs,shuffle 将就地打乱元素,这意味着函数将返回None

    在您的列表构造函数和理解示例中,您创建的列表是从您的 shuffle 函数调用返回的 Nones 的列表。如果您要再次迭代 foo,它们应该被洗牌。

    在第二个到最后一个示例中,您说map()“什么都不做”并且元素保持相同的顺序,这只是因为 shuffle 函数的执行已被推迟,直到您尝试迭代返回值您对地图的调用:

    new_iterator = map(shuffle, foo)
    for element in new_iterator:
        pass
    

    在这个 sn-p 中,每个元素都是 None,就像你观察到的那样。但是迭代 map 将返回的生成器的行为将导致 shuffle 函数实际被执行,如果你再次查看 foo,它现在应该被 shuffle。

    最后一点:我上面写的 sn-p 是一种愚蠢的方式来做你想做的事情。为了仍然在一行中完成你想要的,你可以做一个列表理解,然后扔掉Nones的列表:

    [shuffle(element) for element in foo]
    

    不要将结果列表分配给任何东西。如果你再看foo,子列表应该是洗牌的。

    【讨论】:

    • 好的,谢谢。我可以以某种方式对列表 foo 进行洗牌,而不是像 rightfolds 答案中那样以几行代码或新方法 my_shuffle 结束吗?
    • @ascenator 见编辑。使用显示的列表推导而不将结果列表分配给任何东西。
    【解决方案2】:

    shuffle 打乱列表就地,并通过命令-查询分离原则返回None 而不是列表。你可以这样包装它:

    def my_shuffle(xs):
        xs = list(xs)
        shuffle(xs)
        return xs
    

    这将使输入列表保持不变,并返回一个被打乱的新列表。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-02-01
      • 1970-01-01
      • 2018-12-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多