这个列表理解 pythonic 够吗?

Is this list comprehension pythonic enough?

假设我想使用 Python 创建一个 ints 列表,其中包含数字 1 到 10 的立方体 如果 立方体能被四整除

我写了这条工作线:

cube4 = [x ** 3 for x in range(1, 11) if (x ** 3) % 4 == 0]

我对这行代码的不满是它计算了两次 x 的立方。有没有 more pythonic 的方式来写这行?或者这是否与列表理解一样好?


编辑 - 我的问题旨在关注如何使用 Python 的功能和细微差别避免无关的计算,同时仍然保持代码简洁和可读。虽然这个解决方案可能已经通过查看其他问题得到,但我想确保我知道这个问题的最佳答案,而不仅仅是一个有效的解决方案。

您可以使用生成器表达式:

cubed = (x ** 3 for x in range(1, 11))
cube4 = [c for c in cubed if c % 4 == 0]

这仍然仅在 range() 上迭代 一次 ,但现在 x ** 3 表达式仅在迭代生成器表达式时计算一次。您可以将其合并为一行:

cube4 = [c for c in (x ** 3 for x in range(1, 11)) if c % 4 == 0]

但是将生成器表达式放在单独的一行可能有助于理解(没有双关语意)。

演示:

>>> [c for c in (x ** 3 for x in range(1, 11)) if c % 4 == 0]
[8, 64, 216, 512, 1000]

当然,从数学上讲,对于您的简单示例,您可以只使用 [x ** 3 for x in range(2, 11, 2)],但我怀疑这不是您问题的目的。 :-)

一个数的立方能被 4 整除当且仅当它是偶数。如果将每个数字扩展为其质因数,则很容易看出这一点。因此:

cube4 = [x ** 3 for x in range(1, 11) if x % 2 == 0]

我喜欢单行代码,但值得注意的是还有另一种 Pythonic 方式可以生成所需的 list

cube4 = []
for x in range(1, 11):
    y = x ** 3
    if not y%4:
        cube4.append(y)