创建带有序列号的列表

2024-04-18 04:38:17 发布

您现在位置:Python中文网/ 问答频道 /正文

from time import time

mylist1 = []
mylist2 = []

start1 = time()
for i in range(100000000):
    mylist1.append(i)
end1 = time()

start2 = time()
mylist2 = [0] * 100000000
end2 = time()

print(end1-start1, end2-start2)

当我对这两个操作进行计时以填充列表时,使用for循环得到14秒,使用mylist2 = [0] * 100000000得到0.5秒

因此,如果我需要一次插入大量项目,那么使用第二种方法似乎是显而易见的。你知道吗

但如果我做第二件事,我必须插入相同的数字为所有,或手动键入数字,将重复。你知道吗

有表演的方法吗

for i in range(100000000):
    mylist1.append(i)

这个动作导致[0,1,2,3,…,n]以良好的速度?你知道吗

如果速度快,代码不一定要短。你知道吗


Tags: 方法infromfortimerange数字速度
3条回答

对于完全可移植性,list(range(N))将获得最佳性能as Prune notes。也就是说,如果您纯粹是针对Python3.5或更高版本,那么可以使用PEP 448's additional unpacking generalizations稍微加快速度,包括:

[*range(N)]

请注意,这是一个固定的节省,而不是每个项;它所做的只是绕过对内置命名空间中list的查找,以及普通list构造函数的通用函数调用分派和__init__参数处理。因此,当您谈论1亿个项目时,节省的成本将在噪音中丢失;所有这些都将减少固定开销(在我的3.6安装中)170±10纳秒(例如,list(range(0))每次调用需要417纳秒,而[*range(0)]每次调用需要247纳秒)。你知道吗

但在特定情况下,还有一个更快的选择:

mynotlist = range(100000000)

在现代Python中,^{} objectsfull fledged sequences,它们是不可变的。因此,您可以构造它们、索引它们、切片它们、计算它们的长度、向前和向后迭代它们、检查成员资格(在O(1)中检查int的成员资格,不像list中的成员资格测试是O(n)),等等。它们唯一缺少的不可变相关特性是连接和重复(使用+*),尽管可以用^{} functions来模拟,比如^{}(用于串联),和^{}inga ^{}(用于重复)。你知道吗

如果您不需要改变序列,只需从中读取,使用range“raw”是迄今为止最好的选择;range是懒惰的,不消耗内存,同时仍然非常有效地生成它们的值。这种懒惰可能很重要;list(range(100000000))需要(在64位Python上)3.45giga字节的内存来存储list本身以及它包含的所有intrange(100000000)需要48字节。考虑到内存的节省,动态生成值的琐碎成本是非常值得的。你知道吗

如果需要可变性,仍然可以节省一点内存。如果numpy是一个选项,那么sacul's answer已经覆盖了您;如果不是,那么Python's array module将为您节省一点时间和大量内存。与之相比:

 list(range(100000000))

array备选方案:

 array.array('I', range(100000000))

所需时间减少了约10%(微基准点在3.39秒时有list,而在3.07秒时有array.array),并且占用的内存更少(低于~391 MB,而intlist的~3529 MB)。array的主要成本是有限的值范围(例如,对于'I',四字节unsigned int只能将值存储在range(2**32);使用两倍内存的q/Q格式代码的最大范围是range(-2**63, 2**63)/range(2**64))。你知道吗

尝试列出range输出:

mylist3 = list(range(100000000))

我在你的测试中加了这个

append: 18.42
all-0:   0.23
list:    2.63       <== The new one

既然你说你需要速度,我认为np.arange是最好的方法,它甚至比创建所有0的列表还要快

import timeit
import numpy as np

def m1(n=100000000):
    mylist = []
    for i in range(n):
        mylist.append(i)
    return mylist

def m2(n=100000000):
    return [0] * n

def m3(n=100000000):
    return list(range(n))

def m4(n=100000000):
    return np.arange(n)

>>> timeit.timeit(m1,number=1)
17.615584995000972
>>> timeit.timeit(m2,number=1)
0.7669911839911947
>>> timeit.timeit(m3,number=1)
9.909814337006537
>>> timeit.timeit(m4,number=1)
0.5374436590063851

注意,np.arange()返回一个np.array。如果需要将其转换回列表,则会失去速度。最好用数组。。。你知道吗

def m4(n=100000000):
    return np.arange(n).tolist()

>>> timeit.timeit(m4,number=1)
11.485261309993803

相关问题 更多 >