迭代后过滤器对象变空? [重复]

问题描述 投票:0回答:2

我正在学习如何使用

filter
功能。

这是我写的代码:

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))

第二次,我得到一个空列表。

你能解释一下为什么吗?

python python-3.x
2个回答
23
投票

这是一个经典的 python3 doh!.

过滤器是一种可以迭代的特殊可迭代对象。然而,就像生成器一样,您只能迭代它一次。因此,通过调用

list(people2)
,您将迭代
filter
对象的每个元素以生成
list
。此时,您已到达可迭代的末尾,并且没有任何可返回的内容。

因此,当您再次调用

list(people2)
时,您会得到一个空列表。

演示:

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

我应该提到,对于 python2,

filter
返回一个列表,所以你不会遇到这个问题。当你将 py3 的惰性求值引入图片中时,问题就出现了。


1
投票

这是因为过滤器真正返回的是一个迭代器。 在您开始使用其结果之前,此迭代器实际上不会执行任何操作 - 在本例中,当您将其转换为列表时。

people2
是准备过滤人员列表的东西;然后,当对其调用 list 时,它会迭代人员列表并提供过滤后的结果。 现在迭代器已经完成,没有什么可以迭代的了,所以当你第二次调用 list 时,那里什么也没有了。

阅读本文了解更多详细信息 - Python 中的惰性求值

© www.soinside.com 2019 - 2024. All rights reserved.