【问题标题】:What is the best way to reset (re-initialize) a list of integers (to 0) in Python在 Python 中重置(重新初始化)整数列表(为 0)的最佳方法是什么
【发布时间】:2020-07-07 19:07:18
【问题描述】:

给定一个固定大小 (n) 的整数列表 (list_nb),将所有值重置(重新初始化)为 0 的最佳方法是什么。

我已经尝试了两种方法,1) 使用循环来一个一个地重置所有元素,2) 一个相同大小的新列表(所有元素都为 0)。

第二种方法显然在执行时间方面提供了更好的结果。

import time

n = 200_000_000
list_nb = [0]*n

# some lines of code that change the list_nb ....

# method 1 to reset
start_time = time.time()
for i in range(len(list_nb)):
    list_nb[i] = 0
end_time = time.time()
print("Method 1 time = ",end_time-start_time," s")

# method 2 to reset
start_time = time.time()
list_nb = [0]*n
end_time = time.time()
print("Method 2 time = ",end_time-start_time," s")

结果:

  • 方法 1 时间 = 16.05620765686035 秒
  • 方法 2 时间 = 1.279524564743042 秒

不知道有没有其他办法。

谢谢。

【问题讨论】:

    标签: python list time reset


    【解决方案1】:

    方法 2 显然在速度上更胜一筹,对于熟悉 Python 序列乘法的人来说很容易理解。警告:它不会重置list内容;它正在创建一个全新的list,并重新绑定这个新的list 的名称。因此,如果list_nb 是函数的参数,则调用者的list 副本不会被更改。如果这就是您想要的,那很好,但是如果您想要更改内容,请将其更改为:

    list_nb[:] = [0]*n  # Or itertools.repeat(0, n), though CPython doesn't speed it up
    

    它使用切片分配来替换现有list 的内容。它花费的时间大约是list_nb = [0]*n 的两倍(它构建一个新的list,从中复制,然后将其丢弃),但如果您需要就地突变,这是值得的。

    【讨论】:

    • 非常感谢,确实,这是一个非常好的观点(我没有考虑过)。在执行时间方面,它给出了两倍以上;对于此示例,它与方法 1(遍历所有元素)几乎相同。如果更改大小,我们发现您提出的方法比遍历所有元素更快。
    • @ibra:在您的原始示例中,方法 1 的时间是方法 2 的 10 倍多,我的“方法 3”只有大约 2 倍,而不是“与方法 1 几乎相同” .
    • 使用 n= 200_000_000 (在我的机器上)==> 方法 1(循环)= 15.41 s |方法 2(新列表)= 1.26 s |方法 3(使用 numpy)= 0.44 s |方法 4(您的方法:使用切片分配)= 12.77 s || n= 300_000_000 ==> 方法 1(循环)= 24.94 s |方法 2(新列表)= 1.88 秒 |方法 3(使用 numpy)= 0.66 s |方法 4(使用切片分配)= 19.03 s。我不知道为什么你的机器是 2 倍,而我的大约是 10 倍(使用切片分配与新列表)! .非常感谢@ShadowRanger
    • 确实进行了更多测试,使用相同的参数(n=200_000_000 和 n=3_0...),是的,我给出的结果是(新列表)的 2 倍,你是对的 :)。但我不明白为什么测试会在 10 倍和 2 倍之间给出如此不同的结果。非常感谢:)
    • @ibra:我建议使用timeit.repeat 方法而不是time;它提供了更多可重复的结果。
    【解决方案2】:

    我认为最好的方法是覆盖列表,就像您在方法 #2 中所做的那样。覆盖现有列表比用 0 替换列表中的每个元素更容易。我相信没有更快的方法可以做到这一点,但我可能错了。干得好!

    【讨论】:

    • Thank :) ,看来@Necklondon 和 jvieira88 提出的解决方案更快。
    【解决方案3】:

    使用 numpy 非常快。

    import numpy as np
    import time
    
    n= 200000000
    
    start_time = time.time()
    list_nb = np.zeros(n)
    end_time = time.time()
    print(end_time-start_time)
    

    这需要我0.003000497817993164

    【讨论】:

    • 谢谢 :) ,是的,它确实提供了更好的结果(在执行时)。 list_nb = list_nb = np.zeros(大小,dtype = int)。方法 1 时间 = 19.04 秒;方法 2 时间 = 1.27 秒;方法 3 时间 = 0.44 秒。谢谢。
    • 除了速度更快,但它有一个缺点,当我们想将它与现有列表一起使用(例如连接)时,我们必须将其转换为列表( (np.zeros(size,dtype =int)).tolist() ),这比仅仅创建一个新列表(方法 1)提供了更多的时间。
    【解决方案4】:

    如果你准备好使用 numpy:

    start_time = time.time()
    a = numpy.zeros(n, dtype=object) 
    end_time = time.time()
    print("Method 0 time = ",end_time-start_time," s")
    

    给予

    ('Method 0 time = ', 0.8265918731689453, ' s')
    

    【讨论】:

    • 谢谢 :) ,是的,它确实提供了更好的结果(在执行时)。我只是将对象更改为 int, a = numpy.zeros(n, dtype=int)
    • 除了速度更快,但它有一个缺点,当我们想将它与现有列表一起使用(例如连接)时,我们必须将其转换为列表( (np.zeros(size,dtype =int)).tolist() ),这比仅仅创建一个新列表(方法 1)提供了更多的时间
    猜你喜欢
    • 2013-12-30
    • 1970-01-01
    • 2011-03-13
    • 2010-10-13
    • 2010-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-01
    相关资源
    最近更新 更多