Python中执行for elem in A[a:b]遍历是否会复制数组?
问题解答
1. for elem in A[a:b] 的运行逻辑
这个写法的实际行为完全取决于A所属的类型:
- 如果
A是Python原生列表(list):
执行切片操作A[a:b]时,会直接在内存中复制该区间内的所有元素,生成一个全新的子列表,后续遍历实际是在遍历这个新生成的临时子列表。如果切片区间很大,会产生和切片元素总量相等的额外内存开销。 - 如果
A是支持视图机制的序列(比如numpy数组):A[a:b]不会复制原数据,只会生成一个记录了原数组引用、起止位置、步长的视图对象,遍历的时候直接访问原数组对应位置的元素,不会产生大量额外内存占用。
2. 和range写法的内存占用对比
两者的内存占用是否一致,同样和A的类型相关:
- 对于Python原生列表:两者内存占用完全不同。
range在Python3中是惰性可迭代对象,本身只存储起止值、步长三个属性,几乎不占额外内存,遍历过程中直接通过索引访问原列表的元素,除了循环变量没有其他额外开销,内存占用远低于切片复制的写法。 - 对于支持视图的序列类型:两者内存占用基本一致,都不会复制原数据,仅会产生少量存储元数据的内存开销。
补充优化方案
如果遍历大的原生列表时不想额外占用内存,又不想手动写索引遍历,可以用itertools.islice实现惰性切片迭代:
from itertools import islice for elem in islice(A, a, b): something(elem)
这个写法不会复制切片数据,内存占用和range写法基本一致。
内容的提问来源于stack exchange,提问作者arthll
相关产品推荐
相关产品推荐

