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

2024-09-28 22:25:18 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在学习如何使用filter函数。在

这是我写的代码:

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

people2 = filter(lambda x: "height" in x, people)

正如您所看到的,我试图做的是删除所有不包含'height'键的字典。在

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

^{pr2}$

我得到:

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

问题是如果我做两次:

print(list(people2))
print(list(people2))

第二次,我得到一个空名单。在

你能解释一下为什么吗?在


Tags: lambda函数代码namein字典samfilter
2条回答

这是一只经典的Python!。在

过滤器是一个特殊的可迭代对象。不过,你只能像生成器一样重复一次。因此,通过调用list(people2),您正在迭代filter对象的每个元素来生成list。此时,您已经到达iterable的末尾,没有其他内容可返回。在

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

演示:

>>> l = range(10)
>>> k = filter(lambda x: x > 5, l)
>>> list(k)
[6, 7, 8, 9]
>>> list(k)
[]

我应该提到,对于python2,filter返回一个列表,因此您不会遇到这个问题。当您将py3的懒惰求值引入图片中时,问题就出现了。在

这是因为过滤器真正转换的是一个迭代器。在您开始使用迭代器的结果之前,这个迭代器实际上不会做任何事情,在本例中,当您将其强制转换为列表时。people2是一个可以过滤人员列表的东西,当对其调用list时,它会遍历人员列表并传递过滤后的结果。现在迭代器已经完成了,就并没有什么可以迭代的了,所以当您第二次调用它的list时,这里就什么也没有了。在

阅读本文了解更多细节-Lazy evaluation python

相关问题 更多 >