在Python中,列表(list)是可变结构,而元组(tuple)是不可变的。
示例,说明列表和元组的变化:
lst = [1, 2, 3] lst.append(4) # OK lst[1] = 20 # OK tup = (1, 2, 3) tup[1] = 20 # TypeError
性能:
问题: 为什么向列表添加元素的操作通常很快(O(1)),如果从数组的角度来看,这应该导致内存的重新分配?
答案:
Python实现了动态数组,"立即为多个元素分配额外内存"。因此,append通常占用O(1),而内存重新分配只发生在实际耗尽保留块时。
示例:
import sys lst = [] for i in range(10): lst.append(i) print(len(lst), sys.getsizeof(lst)) # 内存大小增长不是严格线性的
历史
在一个项目中,为字典的键使用了list。开发者不知道列表不哈希(可变性),这导致了错误"TypeError: unhashable type: 'list'"。
开发者经常通过+连接来创建长列表。这导致了额外的数组复制和高内存和时间开销。使用循环中的append或生成器更有效。
在日志系统中,为存储时间戳选择了元组,认为由于不可变性会更快。但偶尔需要修改,这就要求不断创建新的元组(写时复制),导致性能较使用列表时下降。