在切片列表时,Python是否复制对对象的引用?

在切片列表时,Python是否复制对对象的引用?,python,list,memory,copy,slice,Python,List,Memory,Copy,Slice,当列表被切片时,对其内容的引用是否从原始列表复制?我可以想象这可能没有必要,但我读到了相反的内容() 这个问题很重要,例如对于下面的习惯用法,在一个很长的my\u列表的情况下: for (first_elmt, second_elmt) in itertools.izip(my_list[:-1], my_list[1:]): … 一份拷贝可能会占用内存,也可能会占用一些时间。我比较了使用xrange()在1亿个整数的列表上循环索引first\u elmt。切片方法实际上快了20%,但

当列表被切片时,对其内容的引用是否从原始列表复制?我可以想象这可能没有必要,但我读到了相反的内容()

这个问题很重要,例如对于下面的习惯用法,在一个很长的
my\u列表的情况下:

for (first_elmt, second_elmt) in itertools.izip(my_list[:-1], my_list[1:]):
    …
一份拷贝可能会占用内存,也可能会占用一些时间。我比较了使用
xrange()
在1亿个整数的列表上循环索引
first\u elmt
。切片方法实际上快了20%,但似乎复制了引用(系统时间更长)。真的是这样吗


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

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

l = [object() for i in xrange(100000000)]
然后你做一个切片:

l2 = l[:-1]
l2
将拥有自己的9999999指针备份数组,而不是共享
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
停止这一事实。这可以扩展到您已经在使用迭代器的情况


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

l = [object() for i in xrange(100000000)]
然后你做一个切片:

l2 = l[:-1]
l2
将拥有自己的9999999指针备份数组,而不是共享
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
停止这一事实。这可以扩展到您已经在使用迭代器的情况


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

是的,切片确实复制引用,事实上,以这种方式复制列表是一种习惯用法:
newlst=lst[:]
似乎复制了数据
-不,它永远不会这样做。事实上,除非你明确要求,否则永远不会有任何数据复制。我同意。我的意思是“复制参考资料”,正如我在标题和问题的开头所写的那样。
似乎在复制数据。
-不,它永远不会这样做。事实上,除非你明确要求,否则永远不会有任何数据复制。我同意。我的意思是“复制参考资料”,正如我在标题和问题的开头所写。你有关于参考资料副本的参考资料吗?现在我想起来了,复制它们是有意义的,不过,以防原始列表被修改。另一点:我发现直接使用
itertools.islice(…,1,None)
,而不是
next(…,None)
,因为它明确地是一个切片(并且不需要像
next()
那样的任意默认值)。@EOL:来自教程:“所有切片操作都返回一个包含请求元素的新列表。这意味着以下切片返回列表的新(浅层)副本:
>>squares[:]
“。你也可以看看。谢谢!这是我在10年前阅读教程时不记得的DDo您有关于参考资料副本的参考资料吗?现在我想起来了,复制它们是有意义的,不过,以防原始列表被修改。另一点:我发现直接使用
itertools.islice(…,1,None)
,而不是
next(…,None)
,因为它明确地是一个切片(并且不需要像
next()
那样的任意默认值)。@EOL:来自教程:“所有切片操作都返回一个包含请求元素的新列表。这意味着以下切片返回列表的新(浅)副本:
>>squares[:]
>”。您也可以查看。谢谢!这是我10年前阅读教程时不记得的内容。:DGood point。这确实是期望切片复制引用的另一个原因(除此之外,即使原始列表发生变化,切片也不会发生变化)。这一点很好。这确实是期望切片复制引用的另一个原因(除此之外,即使原始列表发生变化,切片也不会发生变化)。