对于某些数据,如:
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的元素,但第二件事呢?
答案 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
,则应该对这些子列表进行洗牌。