如何正确使用Python3地图?

问题描述:

对于像一些数据:如何正确使用Python3地图?

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

我可以使用map(shuffle, foo)的Python 2洗牌FOO的每个子表,并取回从地图列表。

Python 3 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的元素,但第二个呢?

根据the docs随机洗牌将就地洗牌,这意味着该函数将返回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,应该洗牌子列表。

+0

好的,谢谢。我可以以某种方式对列表foo进行洗牌,而不是最终得到几行代码或像rightfolds回答中的新方法my_shuffle? – daniel451 2014-12-07 00:39:22

+0

@ascenator请参阅编辑。使用显示的列表理解而不将结果列表分配给任何东西。 – skrrgwasme 2014-12-07 00:51:42

+0

谢谢,这解决了问题:) – daniel451 2014-12-07 00:56:27

shuffle洗牌清单就地并且由命令查询分隔原则返回None而不是列表。你可以用它像这样:

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

这将使输入列表不变,并返回其洗牌的新列表。

+0

Ahh没有仔细阅读问题。 – Dair 2014-12-07 00:33:54