频繁回溯时选生成器还是列表?大数字列表约数求和最优方案
咱们来逐个拆解你的问题:
问题1:当需要频繁回到序列起始位置时,使用生成器还是列表更合适?
答案很明确:列表更合适。
生成器的核心特性是「惰性生成」——每次调用生成器函数(比如你写的sieve_of_eratosthenes)都会从头执行生成逻辑,而且迭代过的元素不会被保存。你没法让生成器「倒回去」重新遍历,只能重新调用它,这意味着每次都要重复一遍生成元素的计算过程,开销很高。
而列表是把所有元素一次性生成并存储在内存里,你可以随时从头遍历、反复遍历,不需要重复执行生成逻辑。所以如果需要频繁回到序列起始位置,列表的效率会高很多,尤其是生成逻辑本身比较耗时的场景(比如你的埃氏筛法)。
问题2:求大型数字列表的约数和,用质数生成器还是列表更好?
先看你现在的代码逻辑:
for n in numbers_list: s = 0 for p in sieve_of_eratosthenes(limit): if not n % p: # 这里你代码里写的x应该是n吧? s += p
这个写法的问题非常大:你每处理一个数字n,就重新跑一遍埃氏筛法!埃氏筛法本身的时间复杂度是O(limit log log limit),如果你的numbers_list有上千甚至上万个元素,那整体时间开销会是单个筛法的上千倍,完全是没必要的重复劳动。
对你的场景来说,直接创建质数列表绝对是更好的选择:
- 先提前生成一次质数列表:
primes = list(sieve_of_eratosthenes(limit)) - 然后用这个预生成的列表去处理每个数字:
for n in numbers_list: s = 0 for p in primes: if not n % p: s += p # 后续处理s的逻辑
这样只需要执行一次筛法的昂贵计算,后续遍历预生成的质数列表几乎没有额外开销,整体性能会提升几个数量级。
当然,如果你的limit大到内存存不下所有质数(比如limit是1e9),那可能需要其他优化方案,但一般来说,处理大型数字列表的约数和场景,预生成质数列表是性价比最高的做法。
内容的提问来源于stack exchange,提问作者CIsForCookies
相关产品推荐
相关产品推荐

