Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/298.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python iadd运算符(+;=)与简单加法有何不同?_Python_Syntax - Fatal编程技术网

Python iadd运算符(+;=)与简单加法有何不同?

Python iadd运算符(+;=)与简单加法有何不同?,python,syntax,Python,Syntax,我一直认为x+=1只是语法上的简写(完全等同于)x=x+1,直到我花了一段时间试图弄清楚为什么这段代码没有按预期的方式运行: [ipython/euler 72 ]$ def func(mylist): mylist += random.sample(range(100),2) # do stuff with the random result, then restore original list mylist = mylist[:-2] 它应该返回它得到的相同列表,

我一直认为
x+=1
只是语法上的简写(完全等同于)
x=x+1
,直到我花了一段时间试图弄清楚为什么这段代码没有按预期的方式运行:

[ipython/euler 72 ]$ def func(mylist):
    mylist += random.sample(range(100),2)
    # do stuff with the random result, then restore original list
    mylist = mylist[:-2]
它应该返回它得到的相同列表,但它似乎不是这样工作的:

[ipython/euler 81 ]$ x = [1,2,3]

[ipython/euler 82 ]$ func(x)
[1, 2, 3, 23, 7]

[ipython/euler 83 ]$ func(x)
[1, 2, 3, 23, 7, 42, 36]

[ipython/euler 84 ]$ func(x)
[1, 2, 3, 23, 7, 42, 36, 0, 5]
如果我将赋值语句更改为长格式
mylist=mylist+…
,它将按预期工作并保持列表不变

为什么会这样?我假设这与列表是可变的,当作为列表的重载方法调用时,iadd可能不是“真实”的加法有关,但我仍然希望解释器将它们视为等价的

mylist += random.sample(range(100),2)
将列表
mylist
就地修改(这就是为什么它被称为
iadd
:就地添加)。这意味着它会更改调用方作用域中的原始列表

mylist = mylist[:-2]
创建一个新的本地对象
mylist
,并将全局
mylist[:-2]
的内容分配给它。这个新的本地对象从函数返回后立即被丢弃。

mylist += random.sample(range(100),2)
将列表
mylist
就地修改(这就是为什么它被称为
iadd
:就地添加)。这意味着它会更改调用方作用域中的原始列表

mylist = mylist[:-2]
创建一个新的本地对象
mylist
,并将全局
mylist[:-2]
的内容分配给它。这个新的本地对象在从函数返回后立即被丢弃。

第一个代码(
mylist+=random.sample(范围(100),2)
)将修改列表,正如您所意识到的那样

这两项:

mylist = mylist + ...
mylist = mylist[:-2]
创建一个名为
mylist
的新对象,然后为该对象指定与先前的
mylist
相同的值(或从中派生的值)

由于这个原因,后一行不会恢复原始列表;它创建了一个新的副本,并保留了原始引用

通过更改适当的列表,您可以获得所需的行为:

mylist[:] = mylist[:-2]
第一个代码(
mylist+=random.sample(范围(100),2)
)修改列表,正如您所意识到的那样

这两项:

mylist = mylist + ...
mylist = mylist[:-2]
创建一个名为
mylist
的新对象,然后为该对象指定与先前的
mylist
相同的值(或从中派生的值)

由于这个原因,后一行不会恢复原始列表;它创建了一个新的副本,并保留了原始引用

通过更改适当的列表,您可以获得所需的行为:

mylist[:] = mylist[:-2]

因为关于
global
的评论而试图否决投票。。。如果他添加了
global mylist
,那么他的原始列表仍将被称为
x
,因此代码肯定不会像预期的那样运行;使用globals来实现这一点肯定不是一个好办法。您可以在列表的开头复制列表,也可以在整个过程中对其进行修改,例如使用
pop
两次,而不是在末尾进行切片。@l4mpi:您说得对,我应该删除此列表。谢谢。因为关于
global
的评论,我很想投反对票。。。如果他添加了
global mylist
,那么他的原始列表仍将被称为
x
,因此代码肯定不会像预期的那样运行;使用globals来实现这一点肯定不是一个好办法。您可以在列表的开头复制列表,也可以在整个过程中对其进行修改,例如使用
pop
两次,而不是在末尾进行切片。@l4mpi:您说得对,我应该删除此列表。谢谢,谢谢!现在,我知道为什么了。谢谢!现在,我知道为什么了。