Python 过滤对象在迭代后变为空?

Python 过滤对象在迭代后变为空?,python,python-3.x,Python,Python 3.x,我正在学习如何使用过滤器功能 这是我写的代码: people = [{'name': 'Mary', 'height': 160}, {'name': 'Isla', 'height': 80}, {'name': 'Sam'}] people2 = filter(lambda x: "height" in x, people) 正如您所看到的,我正在尝试删除所有不包含'height'键的字典 代码正常工作,事实上,如果我这样做: print(list

我正在学习如何使用
过滤器
功能

这是我写的代码:

people = [{'name': 'Mary', 'height': 160},
          {'name': 'Isla', 'height': 80},
          {'name': 'Sam'}]

people2 = filter(lambda x: "height" in x, people)
正如您所看到的,我正在尝试删除所有不包含
'height'
键的字典

代码正常工作,事实上,如果我这样做:

print(list(people2))
我得到:

[{'name': 'Mary', 'height': 160}, {'name': 'Isla', 'height': 80}]
问题是如果我做两次:

print(list(people2))
print(list(people2))
第二次,我得到一张空名单


你能解释一下原因吗?

这是一条经典的蟒蛇3-doh

过滤器是一种特殊的可迭代对象。然而,就像生成器一样,您只能对其迭代一次。因此,通过调用
list(people2)
,您正在迭代
filter
对象的每个元素以生成
list
。此时,您已到达iterable的末尾,没有更多可返回的内容

因此,当您再次调用
list(people2)
时,您会得到一个空列表

演示:


我应该提到,对于python2,
filter
返回一个列表,所以您不会遇到这个问题。当您将py3的惰性计算引入到图片中时,问题就出现了。

这是因为过滤器真正转变的是迭代器。在您开始使用迭代器的结果之前(在本例中,当您将其强制转换为列表时),迭代器不会真正执行任何操作
people2
是一种可以过滤人员列表的东西,当对其调用list时,它会遍历人员列表并提供过滤结果。现在迭代器已经完成了,并没有什么可供它迭代的了,所以当你们第二次调用它的列表时,那个里什么也并没有了


阅读本文了解更多详细信息-

相关:,哦,好吧,如果我想不止一次地使用它,我只需将它保存在另一个变量上,如people3=list(people2),对吗?@L'ultimo Yep,你明白了。好的,真的谢谢你!:)(或者更好的是,我可以直接做people2=filter(lambda x:height,在x中,people))我不理解这个逻辑。filter和map是特殊的对象,它们是否可以在解析后将其重置回起始位置?您仍然可以进行延迟计算,并且可以多次使用。每次调用iter时,从一开始就返回一个新的惰性迭代器。
>>> l = range(10)
>>> k = filter(lambda x: x > 5, l)
>>> list(k)
[6, 7, 8, 9]
>>> list(k)
[]