为何向列表追加字符串时,增强赋值与普通赋值表现不同?
i += 1和i = i + 1在列表操作中表现不同? 哈哈,这个问题真的戳中了Python里很多人容易混淆的点!我当初刚学Python的时候也踩过类似的坑,这俩写法看起来差不多,但底层逻辑真的不一样,你的观察完全正确——它们确实存在本质差异。
1. +=是原地修改操作(in-place)
对于列表这种可变类型,+=调用的是列表的__iadd__()魔法方法,这个方法的核心是直接修改原列表对象本身,而且它接受任何可迭代对象作为右侧参数:会把可迭代对象里的元素逐个拆解出来,追加到原列表中。
所以当你执行a += "ali"时,字符串"ali"是可迭代对象,Python会把它拆成单个字符"a"、"l"、"i",然后逐个加到原列表[1,2]里,最终得到[1,2,"a","l","i"]。这其实和调用a.extend("ali")的效果完全一致。
2. a = a + ...是创建新对象
而+操作符调用的是列表的__add__()方法,这个方法的规则很严格:两边必须都是列表类型。它会把两个列表合并后返回一个全新的列表对象,再把这个新对象重新赋值给变量a。
当你执行a = a + "ali"时,右侧是列表[1,2]和字符串"ali"相加,Python会直接抛出TypeError: can only concatenate list (not "str") to list——因为它根本不允许把列表和字符串这两种不同类型的对象做拼接。
额外补充:不可变类型的特殊情况
如果是处理字符串、元组这类不可变类型,+=和+的行为会更相似,因为不可变类型无法原地修改,+=也会创建新对象。比如:
s = "abc" s += "def" # 等价于 s = s + "def",都是生成新字符串
但回到可变类型(列表、字典等),+=的原地修改特性就会和+的创建新对象行为产生明显差异,这就是你遇到问题的核心原因啦!
内容的提问来源于stack exchange,提问作者Njx

