Operation about list in python
我处于一个非常有趣的情况,我很惊讶。实际上,我认为两个i += 1 and i = i + 1是相同的。但这里不一样;
和output is [1,2,"a","l","i"]。
但如果我这样写的话;
它不起作用。
我真的很困惑。它们不同吗?
- 好。。。i += 1和i = i + 1不一样。前者修改现有对象i,后者创建新对象。也可以尝试a=[]; b=a; a+=[1]—它修改a和b,而a = a + [1]只修改a。
- a=a+"ali"是一个错误,因为不能用字符串连接列表。
- @Zvone真的很有趣。可能对你来说这很正常。但在我的大学里,老师说他们是一样的。我看了很多关于编程的视频。他们都说他们是一样的。我想知道一件事,I+=1的情况下,可以使用而不是其他在每个位置?或不是?因为i+=1也可以创建一个新对象。
- @njx是两个独立的操作,根据对象的不同,它们可以执行相同的操作,也可以不执行相同的操作(i)。对于像int和str这样的内置不可变对象,它们可能也会这样做,因为无法修改对象。对于可变对象,我希望它们是不同的。这仍然不能解释为什么一个接受字符串而另一个不接受,但我不能给你一个更好的答案。对我来说,这实际上是有道理的,但它可以以不同的方式实现。
- @Zvone-不完全是。__iadd__和__add__都返回对象。list.__iadd__返回自身,int.__iadd__返回新对象。因此,x = 1;x += 1创建了一个新的对象。对象本身决定了它们应该做什么。
- @特拉尼:还是不太对。int.__iadd__根本不存在,所以+=又回到int.__add__上去,创造了一个新的对象。list.__iadd__存在,返回修改后的原始列表。
简短回答
+运算符连接列表,而+=运算符扩展具有iterable的列表。
长回答
+运算符连接列表以返回新列表…
1 2 3 4 5
| l1 = l2 = []
l1 = l1 + [1]
l1 # [1]
l2 # [] |
…而+=操作符通过改变列表来扩展列表。
1 2 3 4 5
| l1 = l2 = []
l1 += [1]
l1 # [1]
l2 # [1] |
允许不同行为的是,+调用__add__方法,+=调用__iadd__方法。
在您的示例中,为__iadd__方法提供了一个字符串,这相当于执行l.extend('ali')操作。特别是,可以使用任何iterable扩展列表,但串联参数必须同时是列表。
但是,list.__iadd__和list.extend之间有细微的差别。前者返回突变的列表,而后者则不返回。
1 2 3 4 5
| >>> a = [1,2]
>>> a = a +"ali"
Traceback (most recent call last):
File"<stdin>", line 1, in <module>
TypeError: can only concatenate list (not"str") to list |
对于列表数据类型,使用.append方法:
1 2 3 4
| >>> a = [1,2]
>>> a.append("ali")
>>> a
[1, 2, 'ali'] |
python中的字符串定义为一行中的一系列字符。因此,这些"字符"被添加到"列表"类型中作为字符,而不是作为"字符串"。如果要对列表类型使用+=添加运算符,则必须使用方括号指定添加的变量或值的类型:
1 2 3 4 5 6 7 8
| >>> a = [1,2]
>>> a += ["ali"]
>>> a
[1, 2, 'ali']
>>> a += ["foo",3,"bar"]
>>> a
[1, 2, 'ali', 'foo', 3, 'bar'] |
在Python中,由于不能声明静态类型,所以该行为不会出现,但是如果您查看C++,如果声明EDOCX1×0作为整数,然后执行EDCOX1(1),EDCOX1(2)将变成EDCOX1×3,而EDCOX1(4)将中断。
原因是a += b和a = a + b不一样。在python术语中,a += b只是a.__iadd__(b),a = a + b是a = a.__add__(b),如果不存在,则是a = b.__radd__(a)。不能使用+将列表和字符串一起添加,因此第二个代码不起作用,但+=起作用,因为它会自动将某些类型强制转换为彼此,即将iterables相互转换。您不能执行a = []; a +="",但可以执行相反的操作,因为您可以使用list("...")明确地将字符串转换为列表。