本文转载自微信公众号“东方儿”,作者东方儿。转载本文请联系东方儿公众号。顺序赋值是Python的默认操作。如果使用不当,可能会陷入语法陷阱。++表示将两个序列的元素连接在一起。通常+号两边的序列是由同一类型的数据组成的。在拼接过程中,两个被操作的序列不会被修改,Python会创建一个包含与拼接结果相同类型数据的新序列。例如:a=[1]b=[2]c=a+bprint(a,b,c)print(id(a),id(b),id(c))结果为:[1][2][1,2]240961052448024096105235202409610523648*如果想把一个序列复制几份然后拼接在一起,用整数乘以序列会更快。同样,此操作会产生一个新序列:>>>l=[1]>>>l*5[1,1,1,1,1]>>>5*"a"'aaaaa'+和*都遵循这条规则,不修改原来的操作对象,而是建立一个新的序列。列表和列表的陷阱猜猜结果会是什么:x=["x"]my_list=[x]*3print(my_list)#[['x'],['x'],['x']]x2=my_list[2]x2[0]="y"print(my_list)是合理的,应该是[['x'],['x'],['y']],但是错了,它实际上是:[['y'],['y'],['y']]难以置信!分配my_list的最后一个元素的列表会导致分配所有三个元素的列表!这体现了my_list的三个元素,元素不??是3个列表,而是3个列表引用,指向同一个列表。等同于:x=["x"]my_list=[]foriinrange(3):my_list.append(x)#添加相同的对象x2=my_list[2]x2[0]="y"print(my_list)#[['y'],['y'],['y']]每次都将相同的对象附加到my_list。如果要生成3个不同的列表,则需要在每次迭代中创建一个新列表:my_list=[]foriinrange(3):x=["x"]#Newlistmy_list.append(x)x2=my_list[2]x2[0]="y"print(my_list)#[['x'],['x'],['y']]这符合预期。代码可以通过列表理解来简化:x=["x"]my_list=[xforirange(3)]x2=my_list[2]x2[0]="y"print(my_list)#[['x'],['x'],['y']]课程:创建列表列表,使用列表理解,不要使用*运算符。如果在语句a*n中,序列a中的元素是对其他变量对象的引用,需要特别注意,这可能不是你想要的效果。虽然+=a+=b表示a=a+b,但其背后的特殊方法是__iadd__。如果一个类没有实现这个方法,Python将退后一步并调用__add__。__iadd__方法会直接对原对象进行add,__add__方法会先生成一个新的对象,然后再赋值。*=+=的这些概念也适用于*=,但后者对应的是__imul__。Appending仍然是一个新对象,应用于可变序列和不可变序列时效果明显。例子:#可变序列,追加>>>l=[1,2,3]>>>id(l)2135319475136>>>l*=2>>>l[1,2,3,1,2,3]>>>id(l)2135319475136#idsame#immutablesequence,newobject>>>t=(1,2,3)>>>id(t)2135322139520>>>t*=2>>>id(t)2135321695424#Id不相同的元组集合列表>>>t=(1,2,[30,40])>>>t[2]+=[50,60]猜猜下面4种情况中哪种会发生?a.t变为(1,2,[30,40,50,60])b.因为元组不支持对其元素的赋值,所以会抛出TypeError异常c。以上两个都不是d。a和b都是对的,因为元组不能赋值,所以我会毫不犹豫的选择b。但实际上答案是d!a和b都正确,都会赋值成功,报错:>>>t=(1,2,[30,40])>>>t[2]+=[50,60]traceback(最近调用最后):文件“”,第1行,在
