如何正确使用Python3地图?

时间:2014-12-07 00:24:33

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

对于某些数据,如:

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

我可以在 Python 2 中使用map(shuffle, foo)来混淆foo的每个子列表,并从地图中获取一个列表。

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的元素,但第二件事呢?

2 个答案:

答案 0 :(得分:2)

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

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

这将保持输入列表不变,并返回一个新的列表,该列表被随机播放。

答案 1 :(得分:2)

根据the docs,shuffle会将元素原位洗牌,这意味着该函数将返回None

在列表构造函数和理解示例中,您创建的列表是从您的shuffle函数调用返回的None列表。如果你再次迭代foo,那么它们应该被改组。

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

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

在此代码段中,每个元素都会像您观察到的那样None。但迭代地图将返回的生成器的行为将导致实际执行shuffle函数,如果再次查看foo,它现在应该被洗牌。

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

[shuffle(element) for element in foo]

不要将结果列表分配给任何内容。如果再次查看foo,则应该对这些子列表进行洗牌。