迭代后过滤器对象变空?

L'u*_*imo 5 python python-3.x

我正在学习如何使用该filter功能.

这是我写的代码:

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

people2 = filter(lambda x: "height" in x, people)
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,我要做的是删除所有不包含'height'密钥的字典.

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

print(list(people2))
Run Code Online (Sandbox Code Playgroud)

我明白了:

[{'name': 'Mary', 'height': 160}, {'name': 'Isla', 'height': 80}]
Run Code Online (Sandbox Code Playgroud)

问题是,如果我这样做两次:

print(list(people2))
print(list(people2))
Run Code Online (Sandbox Code Playgroud)

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

你能解释一下为什么吗?

cs9*_*s95 10

这是一个经典的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)
[]
Run Code Online (Sandbox Code Playgroud)

我应该提一下,使用python2,filter返回一个列表,所以你不会遇到这个问题.当你将py3的懒惰评估带入图片时会出现问题.

  • 我不明白这其中的逻辑。filter 和 map 是特殊的对象,它们是否可以在解析后没有将其重置回开始的逻辑?您仍然可以进行延迟评估并且也可以多次使用。每次调用 __iter__ 时,从一开始就返回一个新的惰性迭代器。 (2认同)