我在python 3上使用了map()
和filter()
函数。
我尝试获取一个列表并对其进行过滤,然后在过滤器对象上执行地图功能:
f = list(range(10))
print(f)
print('-----------')
y = filter(lambda a: a > 5, f)
print(list(y))
print(y)
print(type(y))
print('-----------')
x = map(lambda value: value+1, y)
print(list(y))
print(y)
print(type(y))
print('-----------')
print(list(x))
print(x)
print(type(x))
结果是:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
-----------
[6, 7, 8, 9]
<filter object at 0x7f46db255ac8>
<class 'filter'>
-----------
[]
<filter object at 0x7f46db255ac8>
<class 'filter'>
-----------
[]
<map object at 0x7f46db3fc128>
<class 'map'>
当我注释掉print(list(y))
时,它突然运作良好。
你遇到这个了吗?我究竟做错了什么?
我在ubuntu上运行python 3.6.3。
答案 0 :(得分:9)
迭代器和生成器只能使用一次。当您调用list(y)
时,它将产生序列中的所有值,然后将其耗尽。当您第二次尝试查看内容时,没有任何内容可供使用,因此您将获得一个空列表。
以下内容更清楚地证明了这一点:
f = list(range(10))
print(f)
print('-----------')
y = filter(lambda a: a > 5, f)
print(list(y))
print(list(y))
哪个给:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
-----------
[6, 7, 8, 9]
[] # Nothing to yield
如果要将值保留在y
中,则需要将其分配给名称:
y = list(filter(lambda a: a > 5, f))
答案 1 :(得分:1)
我同意roganjosh的回答,但是让我看看是否可以添加一些额外内容:
filter()
,map()
和reversed()
函数有点令人困惑的是,它们不返回列表(如您所料),而是返回迭代器。 (在键入help(filter)
,help(map)
和help(reversed)
时可以阅读的帮助文本中对此进行了说明。)
因此,既然您知道它们返回的是迭代器而不是列表,您可能想知道:为什么这很重要?好吧,迭代器应该迭代一次(即不超过一次),就像在for i in iterator:
这样的for循环中一样。而且要记住的重要一点是,一旦迭代了迭代器,就不再有要迭代的元素了。
为说明起见,请考虑以下代码:
backwards = reversed( [1, 2, 3, 4, 5] ) # creates an iterator; not a list!
myList = list(backwards) # iterates over the iterator to create a list
print(myList) # prints "[5, 4, 3, 2, 1]", as you'd expect
myList = list(backwards) # nothing left to iterate over, so creates an empty list
print(myList) # prints "[]" (an empty list)
那么,如果您想从filter()
,map()
和reversed()
而不是迭代器中获取列表,该怎么办?好吧,您可以立即将这些函数调用包装在list()
中,并在需要时使用该结果,如下所示:
myList = list( reversed( [1, 2, 3, 4, 5] ) )
# Now use myList whenever you need it, without worrying that it will disappear.
或者,您可以将filter()
和map()
替换为列表理解,例如:
f = list(range(10))
y = [a for a in f if a > 5] # you can use this instead of filter()
x = [a + 1 for a in f] # you can use this instead of map()
关于替换reversed()
?试试这个:
z = f[::-1] # you can use this instead of reversed()
您可能想知道:如果我可以使用filter()
,map()
和reversed()
的替代品,为什么还要使用它们?
答案是因为有时您需要过滤,映射或反转一个巨大的列表,而创建另一个(巨大的)列表仅用于循环/迭代会非常浪费和耗时。因此,返回迭代器可防止另一块巨大的内存用完-只需知道迭代器用完(即遍历)时,其信息就会消失。