过滤器和列表推导式的区别

5
我正在使用Python 3,我的问题是为什么输出不同?
print([x * x for x in range(2, 5, 2) if x % 4 == 0]) # returns [16]

q = [x * x for x in range(2, 5, 2)]
print(list(filter(lambda x: x % 4 == 0, q))) # returns [4, 16]
3个回答

4
print(([x * x for x in range(2, 5, 2) if x % 4 == 0]))

在这里,range 的值为 [2,4],只有 [4] 能够通过 if 条件

q = ([x * x for x in range(2, 5, 2)])
print(list(filter(lambda x: x % 4 == 0, q)))

在这里,q 包含每个元素的 x*x,因此列表为 [2*2, 4*4] = [4, 16],并且两个元素都通过了筛选器选择器。


2

由于q包含平方数

In [2]: q
Out[2]: [4, 16]

lambda x: x % 4 == 0会对两个数字都返回True:

In [3]: 4 % 4 == 0
Out[3]: True

In [4]: 16 % 4 == 0
Out[4]: True

列表解析在进行检查后平方数字,但对于2而言这一检查失败了(2 % 42):

In [5]: 2 % 4 == 0
Out[5]: False

因此,2 * 2 = 4 不会包含在列表中。
简而言之,如果您想获得相同的行为,请修改您的列表推导式,在计算余数之前对数字进行平方:
[x * x for x in range(2, 5, 2) if pow(x, 2, 4) == 0] # [4, 16]
#                                   ↖ equivalent to (x ** 2) % 4

1
在前者中,[2,4] 中的每个项都会与 x % 4 == 0 进行比较。而在后者中,filterq 中的每个项(不是 [2,4],而是 [4,16])应用 lambda 表达式。因此,x % 4 == 0 返回 true 两次。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接