迭代过滤器:如何过滤多个元组的列表?

问题描述

我正在解决这个问题,但似乎无法解决。我正在尝试使用filter生成列表。我已经在代码添加prints,看看出了什么问题,filter似乎只关心列表中的最后一个元组。例如,如果我有一个元组列表,则说[(4,1),(16,3),(32,11)] filter仅过滤residuelist中的所有元素:x%32!=11。我是filter函数的新手,所以也许就是它的目的。是否可以在元组列表上进行迭代?

我尝试解决此问题的方法添加一个for

residuelist=range(1,x+1)
for z in requirements:
            for a,b in z:
                residuelist=filter(lambda x: x%a!=b,residuelist)
residuelist=list(residuelist)

但是h(5)显示residuelist仅使用requirements中的最后一个元素进行过滤:

h(5)
[1,2] #unfiltered because requirements=[]
[1,2,3,4] #unfiltered because requirements=[]
[2,4,6,7,8] #filtered with (4,1) because requirements=[(4,1)]
[2,8,10,11,12,14,15,16] #filtered with (4,1)]
[1,5,9,13,16,17,18,20,21,22,23,24,25,26,27,28,29,30,31,32]
#filtered with (16,3) because requirements=[(4,3)]
[[(4,1)],[(16,3)],[(32,5)],11)],13)],17)],21)],23)],25)],29)]]

请不要在[(x,y)]中使用双括号,这是出于某种原因我可以使函数起作用的唯一方法...

解决方法

假设这是Python 3,filter很懒;在尝试迭代结果之前,它实际上不会过滤任何内容。因此,您看到的ab并不是您调用filter时存在的变量,无论迭代器是ab耗尽(当您在循环之外list对其进行验证时)。最简单的解决方法是将ab设为lambda的默认参数,以便它们在定义时绑定,而不是在运行时绑定:

residuelist = range(1,x+1)
for z in requirements:
    for a,b in z:
        residuelist = filter(lambda x,a=a,b=b: x % a != b,residuelist)  # a=a,b=b binds current definitions of a and b
residuelist = list(residuelist)