我有一个列表推导,它打印从1到1000的所有素数。由于某些奇怪的原因,我的列表理解在终端中加载需要1:46。我觉得这很奇怪,因为当我正常地编写相同的代码时,它会立即加载。
这是我的理解:print([x for x in range(2, 1000) if x not in [y * z for y in range(2, 1001) for z in range(2, 1001)if y * z < 1000]])
正如您所看到的,它生成了一个从2到1000的数字列表,并打印出不在1000以下合数列表中的(质数)。当我运行它时,它正确输出,但在我尝试的每台计算机上都需要很长时间。我想可能是我的代码出错了。然而,当我隔离[y * z for y in range(2, 1001) for z in range(2, 1001)if y * z < 1000]
线时,在显示复合材料时没有延迟。当我生成常规的数字列表进行比较时,也没有延迟。只是当我用"not in"的时候;
我想也许不是在比较是特别慢。但令我沮丧的是,我注意到当我正常地写出代码的比较部分而不是理解时,绝对没有延迟。看到这个:
x = [y * z for y in range(2, 1001) for z in range(2, 1001)if y * z < 1000]
newlist = []
for z in range(2, 1000):
if z not in x:
newlist.append(z)
print(newlist)
可以看到,我将组合列表放入一个变量中,并定期执行if语句和循环。如果x不在列表中,则将其添加到新列表中。达到了我理解清单的同样目标。我在想,有没有什么办法可以解决我理解列表这么慢的问题。逻辑符合我最初的理解,所以如果本质上是一样的,为什么用理解的形式要花更长的时间呢?
请尽量不要添加任何额外的功能到我的代码,我试图使用列表理解,只有列表理解。
在x
的每次迭代中重新创建内部列表。简单地把它分开:
composites = [y*z for y in range(2, 1001) for z in range(2, 1001) if y*z < 1000]
[x for x in range(2, 1000) if x not in composites]
顺便说一下,如果你使composites
成为一个集合,查找(in
和not in
)要快得多(O(1)而不是O(n),其中n=len(composites))。
composites = {y*z for y ...}