Python 中过滤器对象的这种行为是否有原因?
Is there a reason for this behavior of the filter object in Python?
>>> a = filter(lambda x: x&1, [1,2])
>>> list(a)
[2]
>>> list(a)
[]
这很违反直觉,不是吗?所以如果有人能解释为什么会这样,请随意!
顺便说下我用的是Python3.8.2
a 是一个可迭代对象,其中的项在您第一次调用 list(a) 时已被消耗。随后的 list(a) 将一无所获。
同样,
a = (i for i in range(10))
list(a)
[0, 1....10]
list(a)
[]
我更喜欢具有不同 IEnumerable 和 IEnumerator 接口的 C# 行为。
既然您知道用 list()
包装对 filter
的调用结果,我假设您熟悉生成器函数及其类似的概念。 filter
函数 returns 实际上类似于生成器函数,因为它只能迭代一次。见下文:
>>> a = filter(lambda x: x^1, [1,2])
>>> type(a)
<class 'filter'>
>>> it = iter(a)
>>> next(it)
2
>>> next(it)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>> it = iter(a) # try to iterate the filter a second time
>>> next(it) # you will get a StopIteration exception the very first time
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>>
以上代码本质上等同于:
a = filter(lambda x: x^1, [1,2])
print(type(a))
for item in a:
print(item)
for item in a:
print(item)
>>> a = filter(lambda x: x&1, [1,2])
>>> list(a)
[2]
>>> list(a)
[]
这很违反直觉,不是吗?所以如果有人能解释为什么会这样,请随意!
顺便说下我用的是Python3.8.2
a 是一个可迭代对象,其中的项在您第一次调用 list(a) 时已被消耗。随后的 list(a) 将一无所获。
同样,
a = (i for i in range(10))
list(a)
[0, 1....10]
list(a)
[]
我更喜欢具有不同 IEnumerable 和 IEnumerator 接口的 C# 行为。
既然您知道用 list()
包装对 filter
的调用结果,我假设您熟悉生成器函数及其类似的概念。 filter
函数 returns 实际上类似于生成器函数,因为它只能迭代一次。见下文:
>>> a = filter(lambda x: x^1, [1,2])
>>> type(a)
<class 'filter'>
>>> it = iter(a)
>>> next(it)
2
>>> next(it)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>> it = iter(a) # try to iterate the filter a second time
>>> next(it) # you will get a StopIteration exception the very first time
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>>
以上代码本质上等同于:
a = filter(lambda x: x^1, [1,2])
print(type(a))
for item in a:
print(item)
for item in a:
print(item)