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

时间:2015-11-10 09:48:42

标签: python list-comprehension

例如,以下代码

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

如何将这段精确的代码转换为列表理解?

3 个答案:

答案 0 :(得分:6)

不,你不能,因为在理解完成迭代之前,列表不作为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中对它进行了测试,并且每次都有一个素数列表。

答案 1 :(得分:1)

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

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的事实,因为对列表的分配返回Noneor评估为右侧值。

这绝对比简单的for-loop更糟糕。我写这篇文章是为了回答OP的问题"什么可能是最接近的模仿,当我除了列表理解之外什么都没有。 (这不是开发代码,只是我的实验)"

也就是说,额外的工作只是添加了 O(n)的工作,所以实际上并没有增加循环的算法复杂性。可以想象(尽管不太可能)列表理解优化会比原始for循环更快。

答案 2 :(得分:0)

#!/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是素数,则返回True,否则返回False。然后,一个名为filter_primes(max)的函数使用is_prime和list comprehension将素数过滤成一个返回的数组。范围的最大数量通过max指定。 main函数只是调用API来测试它。

编辑: 但也许我误解了你的意思,并将这段精确的代码转化为列表理解&#34;。根据您 想要做的事情,使用生成器对于动态目的来说是一个好主意。