2011-08-11 75 views
8

我被要求进行编码测试,但不知道答案。有人有主意吗?[:] = b和a = b [:]之间的区别? (Python)

+0

可能重复[在Python中列表和列表\ [:\]有什么区别?](http://stackoverflow.com/questions/4081561/what-is-the-difference-between-list-and -list-in-python) –

+1

@Ignacio:不,这不是重复的 - 该问题没有提到'a [:] = b'构造。 –

+0

@Adam:甚至没有开始的部分“分配...时”? –

回答

8

[:]是切片运算符。

当它位于左侧时,它会覆盖列表的内容而不创建新的引用。

当它在右侧时,它会创建一个具有相同内容的列表副本。

+0

哦,好吧,现在有道理。为了澄清,在做一个[:] = b时,id(a)不会改变。 id(a)在执行a = b [:]时发生变化。为什么一个人可能比另一个更好? – user701632

+0

是的,你明白了。如果'c'也引用与'a'相同的列表,那么您可能需要更改内容,以便两个变量都引用更新后的列表。 – recursive

1

在这两种情况下,最终列表a是列表b的副本。但用于实现这一点的方法已经改变。

a[:] = b修改列表a,使其具有相同的元素b

a = b[:]产生一个新的列表,它是b副本,并替换列表a

所不同的是,我们是否已经修改现有的列表或创建一个新的列表。

要看到其中的差别:

a = range(3) 
b = range(4) 
c = a # c and a now share the same list 
a[:] = b 
print "a", a 
print "b", b 
print "C", c 

所有三个列表将打印出来的一样。 C和一个共享相同的对象,所以,当a被修改,以便为c

a = range(3) 
b = range(4) 
c = a # c and a now share the same list 
a = b[:] 
print "a", a 
print "b", b 
print "C", c 

现在Ç不会打印出相同的。作业后,ac没有共享同一个对象。

快速,a[:] = b' is probably a little faster then a = b [:]`。第一种形式不必创建新的列表对象,它只能修改现有的列表。其中很大一部分是它可以重新使用列表已经拥有的内存,而不是分配新的内存。

2

a = b[:]呼叫或者在b__getslice____getitem__并将结果a分配。在几乎所有情况下(例如,列表,元组和其他序列类型),这会生成序列的浅表副本;我不知道任何没有实现这种行为的类,但是你可以有一个用户定义的类型来做一些不同的事情。之前提到旧值a的任何其他对象将继续引用旧值。

a[:] = b,在另一方面,来电__setslice____setitem__取代的a与那些序列b的元素的子集。在这种情况下,如果a的序列类型表现良好,则将替换整个a,因为没有端点的范围:表示整个序列。这里的区别是,不可变类型(如元组)不会允许您执行__setslice__(例如通过抛出TypeError异常)。由于底层对象正在被修改,因此之前提到a的任何其他对象也将被更新。

对于可变类型如list,的a = b[:]结果将是相同的a[:] = b,在a将是b浅表副本;对于不可变类型,如tuplea[:] = b无效。对于糟糕的用户定义类型,所有投注都关闭。其他对象引用a - 与a = b[:]相同,它们指的是原始值(a),但a[:] = b指向修改后的对象(b的浅拷贝)。

相关问题