Python2和Python3之间的过滤器行为差异

Python2和Python3之间的过滤器行为差异,python,python-3.x,Python,Python 3.x,我在for循环中的一个列表上做了一系列的过滤,但是在python3中有一些意想不到的结果,而python2给出了预期的结果 比如说, mylist = range(3) for i in range(3): mylist = filter(lambda x: x != i, mylist) print(list(mylist)) 给出了[0,1],但我希望[] 另一个例子是 mylist = range(3) for i in range(3): mylist = filte

我在for循环中的一个列表上做了一系列的
过滤
,但是在python3中有一些意想不到的结果,而python2给出了预期的结果

比如说,

mylist = range(3)
for i in range(3):
    mylist = filter(lambda x: x != i, mylist)

print(list(mylist))
给出了
[0,1]
,但我希望
[]

另一个例子是

mylist = range(3)
for i in range(3):
    mylist = filter(lambda x: x != i, mylist)
    print(list(mylist))

[1, 2]
[]
[]
但我期待着

[1, 2]
[2]
[]

range(3)
更改为
list(range(3))
不会更改输出。

在Python2中,
filter
只会立即返回一个经过筛选的列表

在Python3中,
filter
返回一个filter对象,该对象可以在稍后迭代生成过滤内容。正因为如此,
i
的值在随后的时间被评估成什么才是重要的


您的
i
值没有关闭,因此当过滤器最终运行时(在循环完成并调用
list(mylist)
后),所有三个过滤器都将删除
2
的相同
i

防止这种情况的一种方法是使用函数,在调用时显式绑定
i

def filterWithVal(l, i):
    return filter(lambda x: x != i, l)

mylist = range(3)
for i in range(3):
    mylist = filterWithVal(mylist, i)

print(list(mylist))

受@CharlesDuffy的启发,我还提出了一个想法,使用部分函数强制绑定
I

from functools import partial

mylist = range(3)
for i in range(3):
    mylist = filter(partial(lambda x, i: x != i, i), mylist)

print(list(mylist))

range
是一个迭代器,它在循环中第一次被耗尽,之后为空——如果您将第一行更改为
mylist=list(range(3))
它将按照您的要求执行expect@AnthonySottile我试过了,但没有。哦,我看到你每次迭代都在重击
mylist
,所以除了
list(范围(…)
您还需要
列表(过滤器(…)