修改列表:在python列表中计算素数的筛子

时间:2014-08-11 12:45:28

标签: python list

Euler项目的第10个问题要求我们计算所有素数的总和低于2,000,000。

我的算法是:

  1. 为2,000,000以下的数字构建一个筛子
  2. 总结筛子中的所有数字。
  3. 我对创建多个列表而不是在同一列表上执行计算的代码感到不舒服。

    以下是我的代码:

    def main(number_above):
    list_of_numbers = list(range(number_above))
    list_of_numbers = calculate_sieve(list_of_numbers)
    print summation_of_primes(list_of_numbers)
    
    def calculate_sieve(list_of_numbers):
    
        for prime in list_of_numbers:
    
            if prime >= 2 and prime != 'C':
                multiple = 2
                while multiple * prime < len(list_of_numbers):
                    list_of_numbers[ prime * multiple ] = 'C'
                    multiple += 1
        return list_of_numbers
    
    
    def summation_of_primes(list_of_numbers):
        summation = 0
        for element in list_of_numbers:
            if element != 'C':
                summation += element
        return summation - 1
    

    创建列表的步骤:

    • 首先,创建一个范围(2,000,000)
    • 中的数字列表
    • 其次,此列表将传递给calculate_sieve函数,该函数将取消所有复合。
    • 然后,calculate_sieve函数返回一个列表到主函数。
    • 最后,此列表将传递给求和函数。

    python是否在同一个列表中运行,或者它一次只能保存多个列表? 如果它正在创建列表的多个副本,是否有办法通过在列表中操作来最小化内存使用量?

3 个答案:

答案 0 :(得分:3)

  

python是否在同一个列表中运行?

是的,主要是。

  • 将列表作为参数传递给函数不会创建新列表。
  • 修改列表中的元素不会创建新列表。
  • 从函数返回列表不会创建新列表。

您可能创建重复列表的唯一代码是以下行:

list_of_numbers = list(range(number_above))

在Python 2.7及更低版本中,range已经返回一个列表。在结果上调用list将创建第二个列表。你可以放心地写list_of_numbers = range(number_above)并为自己节省一些记忆。

在3.X中,range会返回range个对象,因此如果您想要随后进行分配,则必须进行list调用,例如list_of_numbers[ prime * multiple ] = 'C'。< / p>

答案 1 :(得分:1)

您可以非常轻松地查看:

In [1]: def some_func(seq):
   ...:     seq.append(1)
   ...:     

In [2]: s = []

In [3]: some_func(s)

In [4]: s
Out[4]: [1]

由于s已修改some_func,因此无法对其副本进行操作。


python中的标识符(或变量)总是引用到对象。它们内存位置。它们是对象的名称。将对象传递给函数时,参数只是创建对该对象的新引用,因此不涉及复制。

答案 2 :(得分:1)

我相信所有的计算都是在相同的列表中执行的,列表是可变的并且它是通过引用传递的,因此我相信在你的情况下,同时只有一个列表在内存中。