python3中map和list迭代器之间的区别 [英] Difference between map and list iterators in python3
问题描述
在python3中使用map和list迭代器时遇到了意外的行为。在这个MWE中,我首先生成一张地图图。然后,我希望每个地图的第一个元素在一个列表中,其余部分在原始地图中:
I ran into unexpected behaviour when working with map and list iterators in python3. In this MWE I first generate a map of maps. Then, I want the first element of each map in one list, and the remaining parts in the original map:
# s will be be a map of maps
s=[[1,2,3],[4,5,6]]
s=map(lambda l: map(lambda t:t,l),s)
# uncomment to obtain desired output
# s = list(s) # s is now a list of maps
s1 = map(next,s)
print(list(s1))
print(list(map(list,s)))
在python 3.4.2中运行MWE会产生s1的预期输出:
Running the MWE as is in python 3.4.2 yields the expected output for s1:
s1 = ([1,4]),
但s的空列表[]。取消注释标记的行会产生正确的输出,如上所述s1,但也有s的预期输出:
but the empty list [] for s. Uncommenting the marked line yields the correct output, s1 as above, but with the expected output for s as well:
s=[[2,3],[5,6]].
文档说地图需要迭代。直到今天,我看到map和list迭代器之间没有区别。有人可以解释这种行为吗?
The docs say that map expects an iterable. To this day, I saw no difference between map and list iterators. Could someone explain this behaviour?
PS:奇怪的是,如果我取消注释第一个print语句,则会打印s的初始状态。所以也可能是这种行为与地图的一种懒惰(?)评估有关?
PS: Curiously enough, if I uncomment the first print statement, the initial state of s is printed. So it could also be that this behaviour has something to do with a kind of lazy(?) evaluation of maps?
推荐答案
A map()
是一个迭代器;你只能迭代一次。例如,您可以使用 next()
获取单个元素,但是一旦用完了项目,就无法获得更多值。
A map()
is an iterator; you can only iterate over it once. You could get individual elements with next()
for example, but once you run out of items you cannot get any more values.
我给你的对象一些更容易记住的名字:
I've given your objects a few easier-to-remember names:
>>> s = [[1, 2, 3], [4, 5, 6]]
>>> map_of_maps = map(lambda l: map(lambda t: t, l), s)
>>> first_elements = map(next, map_of_maps)
迭代 first_elements
这里将依次迭代 map_of_maps
。你只能一次,所以一旦我们用完了元素,任何进一步的迭代都会失败:
Iterating over first_elements
here will in turn iterate over map_of_maps
. You can only do so once, so once we run out of elements any further iteration will fail:
>>> next(first_elements)
1
>>> next(first_elements)
4
>>> next(first_elements)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
list()
做同样的事情;它需要一个可迭代的参数,并将迭代该对象以从结果中创建一个新的列表对象。但是如果你给它一个已经用尽的 map()
,就没有任何东西可以复制到新的列表了。因此,您会得到一个空结果:
list()
does exactly the same thing; it takes an iterable argument, and will iterate over that object to create a new list object from the results. But if you give it a map()
that is already exhausted, there is nothing to copy into the new list anymore. As such, you get an empty result:
>>> list(first_elements)
[]
您需要重新创建 map()
从头开始:
You need to recreate the map()
from scratch:
>>> map_of_maps = map(lambda l: map(lambda t: t, l), s)
>>> first_elements = map(next, map_of_maps)
>>> list(first_elements)
[1, 4]
>>> list(first_elements)
[]
请注意秒 list()
再次调用 map()
对象产生一个空列表对象。
Note that a second list()
call on the map()
object resulted in an empty list object, once again.
这篇关于python3中map和list迭代器之间的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!