我可以在列表理解中形成列表时使用列表吗?

Can I use a list while forming it in a list comprehension?

例如下面的代码

primeList = []
for val in range(2, num):
    if not any(val % i == 0 for i in primeList):
        primeList.append(val)

我怎样才能将这段代码转化为列表理解?

不,你不能,因为在理解完成迭代之前,列表不作为 Python 对象存在。您不能引用不存在的对象。老实说,我只想将其保留为 for 循环 - 列表推导并不是替换所有列表构造循环的灵丹妙药。

但是...您可能会变得棘手并使用仅按需评估的生成器。将此与列表的 extend() 方法相结合,该方法在获取元素时将元素添加到列表中(无论如何在我的测试中),您可以在扩展列表时使用正在扩展的列表的当前内容。

# make sure to set `num`
plist = []
plist.extend(c for c in range(2, num) if not any(c % p == 0 for p in plist))

公平警告:据我所知,extend() 在生成元素时将元素添加到列表中的事实不是规范的一部分,因此这段代码是否有效可能取决于实现.但是我在Python 2.7和3.4测试过,每次都得到一个素数列表。

#!/usr/bin/python
from __future__ import print_function
import math

def is_prime(x):
   if (x == 0 or x == 1 or x < 0):
      return False

   for i in range(2, int(math.sqrt(x)) + 1):
      if (not (x % i)):
         return False 
   return True

def filter_primes(max):
   return [val for val in range(2, max) if is_prime(val)] 

def main():
   primes = filter_primes(20) 
   print(primes)

if __name__ == "__main__":
   main()

上面的代码从定义一个名为 is_prime(x) 的函数开始,如果 x 是素数,则 returns 为真,否则为假。然后一个名为 filter_primes(max) 的函数使用 is_prime 和列表理解将素数过滤到返回的数组中。范围的最大数量通过 max 指定。主函数只是调用 API 来测试它。

编辑: 但也许我误解了 "turn this exact piece of code into list comprehension" 的意思。根据您 真正 想要做什么,使用生成器是实现动态目的的好主意。

实际上,如果您真的想要,您可以在 列表理解中创建列表的相同副本 并参考它...

primeListCopy = []
primeList = [primeListCopy.append(val) or val for val in range(2, num)
                 if not any(val % i == 0 for i in primeListCopy)]

这利用了 primeListCopy.append(val) or val 求值为 val 的事实,因为对列表 returns Noneor 的赋值求值为右侧值。

这在性能方面肯定比简单的 for-loop 更差。我写这篇文章是为了回应 OP 的问题 "what could be the closest mimic when i had nothing but list comprehension. ( this is not a development code, just my experiments)"

也就是说,额外的工作仅 增加了 O(n) 的工作量,因此实际上并没有增加循环的算法复杂性。可以想象(虽然不太可能)列表理解优化将使它比原来的 for 循环更快。