Does Python copy references to objects when slicing a list?

时间:2015-06-14 08:35:36

标签: python list memory copy slice

When a list is sliced, are the references to its contents copied from the original list? I can imagine that this may not be necessary, but I read the opposite ( mentioned in passing)中调用相同的jQuery函数。

这个问题对于以下习语很重要,对于很长的my_list

for (first_elmt, second_elmt) in itertools.izip(my_list[:-1], my_list[1:]):
    …

副本会耗尽内存,大概会消耗一段时间。我将first_elmt的索引与xrange()循环比较,在1亿个整数列表上进行比较。切片方法实际上要快20%,但似乎复制引用(系统时间更长)。确实如此吗?

PS :我现在意识到切片复制引用是很自然的:如果原始列表被修改,切片不会改变,所以更容易实现切片复制原始列表的引用。但是,指向CPython实现的指针会很有趣。

2 个答案:

答案 0 :(得分:2)

切片将复制引用。如果你有1亿件物品清单:

l = [object() for i in xrange(100000000)]

你做了一个切片:

l2 = l[:-1]

l2将拥有自己的99,999,999指针支持数组,而不是共享l的数组。但是,这些指针引用的对象不会被复制:

>>> l2[0] is l[0]
True

如果要迭代重叠的列表元素而不进行复制,可以zip列表中的迭代器已经提前一个位置:

second_items = iter(l)
next(second_items, None) # Avoid exception on empty input
for thing1, thing2 in itertools.izip(l, second_items):
    whatever()

这利用了zip在任何输入迭代器停止时停止的事实。这可以扩展到您已经使用itertools.tee

使用迭代器的情况
i1, i2 = itertools.tee(iterator)
next(i2, None)
for thing1, thing2 in itertools.izip(i1, i2):
    whatever()

答案 1 :(得分:1)

是的,切片DO复制引用,事实上,以这种方式复制列表是一种习惯用法:newlst = lst[:]