我正在解决一个问题,我需要一个零列表,之后我必须更新列表中的一些值。现在我有两个选择,我首先要做的是简单地创建一个零列表,然后更新值,或者我创建一个字典然后更新值。
列出方法:
l=[0]*n
字典方法:
d={}
for i in range(n):
d[i]=0
现在,构建字典的复杂性为O(n)
,然后更新密钥为O(1)
。但我不知道python是如何使用上述方法构建零列表的。
假设n是一个很大的数字,上述方法对于这项任务会更好吗?如何在python中实现list方法? 。另外,为什么上面的列表方法比列表理解方法更快,用于创建零列表?
答案 0 :(得分:2)
预先分配序列后的访问和更新将大致相同。
选择对您的应用程序有意义的数据结构。在这种情况下,我建议列表,因为它更自然地适合“由整数索引的序列”
[0] * n快的原因是它可以一次性制作正确大小的列表,而不是在添加更多元素时不断扩展列表。
答案 1 :(得分:1)
使用timeit
运行测试后:
import timeit
timeit.repeat("[0]*1000", number=1000000)
#[4.489016328923801, 4.459866205812087, 4.477892545204176]
timeit.repeat("""d={}
for i in range(1000):
d[i]=0""", number=1000000)
#[77.77789647192793, 77.88324065372811, 77.7300221235187]
timeit.repeat("""x={};x.fromkeys(range(1000),0)""", number=1000000)
#[53.62738158027423, 53.87422525293914, 53.50821399216625]
正如您所看到的,这两种方法之间存在巨大差异,第三种方法更好但不是列表!原因是创建指定大小的list
比创建dictionary
并且通过迭代扩展它更快。
答案 2 :(得分:1)
我认为在这种情况下你应该只使用list,除非你想在不使用索引的情况下访问某些数据。
Python列表是一个数组。它以特定大小初始化,当需要存储的项目大小超过其大小时,它只是将所有项目复制到新数组,复制为O(k),其中k是列表的大小。这个过程可能会发生很多次,直到列表大小大于或等于n。但是,[0] * n只会创建具有正确大小(即n)的数组,因此比从一开始就将列表更新到正确的大小要快。
对于按列表推导创建,如果您的意思是[0 for i in range(n)]
,我认为它会因更新列表大小而受到影响,因此速度较慢。
Python字典是Hash Table的一种实现,当您插入新的键值对时,它使用哈希函数来计算键的哈希值。散列函数本身的执行相对昂贵,而字典也处理其他情况,如碰撞,这使得它更慢。因此,理论上,字典创建0应该是最慢的。
答案 3 :(得分:1)
Htmlutils.htmlescape
可能是一个更好的解决方案,如果您希望在更新过程中保留初始值时(如果您不依赖collections.defaultdict
),很多元素都不会发生变化。刚
KeyError
要考虑的另一件事是import collections
d = collections.defaultdict(int)
assert d[42] == 0
d[43] = 1
# ...
。如果您只想存储一种类型的元素(计数),则可以使用它。它应该比列表更快,内存效率更高:
array.array