Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.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中的列表操作在函数范围之外运行?_Python_List_Scope - Fatal编程技术网

为什么python中的列表操作在函数范围之外运行?

为什么python中的列表操作在函数范围之外运行?,python,list,scope,Python,List,Scope,在下面的python代码中,变量number被传递到函数addone,并操作本地副本。number的值保持不变 def addone(num): num = num + 1 print "function: added 1, now %d" % num number = 5 print "Before:", number addone(number) print "After:", number 输出: Before: 5 function: added 1, now 6 A

在下面的python代码中,变量
number
被传递到函数
addone
,并操作本地副本。number的值保持不变

def addone(num):
    num = num + 1
    print "function: added 1, now %d" % num

number = 5
print "Before:", number
addone(number)
print "After:", number
输出:

Before: 5
function: added 1, now 6
After: 5
Before: ['A', 'list', 'of', 'words']
function: 'A' was popped!
After: ['list', 'of', 'words']
然而,这种行为似乎与pop、append等列表操作不同。这让我有些困惑。是否所有列表操作都在全球范围内运行?如果是,有什么特别的原因吗

def pop_first(stuff):
    popped = stuff.pop(0)
    print "function: '%s' was popped!" % popped

words = ["A", "list", "of", "words"]
print "Before:", words
pop_first(words)
print "After:", words
输出:

Before: 5
function: added 1, now 6
After: 5
Before: ['A', 'list', 'of', 'words']
function: 'A' was popped!
After: ['list', 'of', 'words']

简单的回答是因为列表是可变的,整数是不可变的


你不能就地改变一个整数,所以我们称之为“不可变的”。记住这一点,像整数加法这样的事情不会修改原始对象,而是返回一个新值——因此原始变量将保持不变。因此,如果我们存储对整数的引用,则只要我们没有更改它们中的任何一个,它们都将是同一个对象:

>>> foo = 1
>>> bar = foo
>>> foo is bar
True
>>> foo += 2
3
>>> foo
3
>>> bar
1
>>> foo is bar
False

另一方面,列表是“可变的”(可以修改相同的对象引用),像
pop()
这样的操作会在适当的位置对
list
进行变异,从而更改原始对象。这也意味着,如果编辑对可变对象(如
列表
)的引用,原始对象也将更改:

>>> baz = [1, 2, 3, 4, 5]
>>> qux = baz
>>> qux is baz
True
>>> baz.pop()
5
>>> qux
[1, 2, 3, 4]
>>> baz
[1, 2, 3, 4]
>>> qux is baz
True

执行
stuff.pop()
操作时,修改对象
stuff
。执行
num=num+1
操作时,不修改
num
,只需创建一个新对象并将其分配给变量
num
。如果
num
是一个列表,结果将完全相同:

def addone(num):
    num = num + [1]
    print "function: added 1, now", num

number = [5]
print "Before:", number
addone(number)
print "After:", number


# Before: [5]
# function: added 1, now [5, 1]
# After: [5]

将对象传递给函数的方式与分配对象的方式相同。因此,你看到的效果与此相同:

>>> words = ["A", "list", "of", "words"]
>>> stuff = words
>>> stuff.pop()
'words'
>>> words
['A', 'list', 'of']
这是因为
stuff
words
是同一个列表,并且
pop
更改了该列表。int是不可变的,这意味着它们不支持任何就地突变:每次更改其值时,它都会给您一个具有新值的不同int对象。您可以使用
is
操作符测试两个对象是相同还是不同的对象:

>>> stuff is words
True
>>> a = 5
>>> b = a
>>> a is b
True
>>> b += 1
>>> a is b
False

因为列表是可变的,但整数不是
num+=1
将不同的对象分配给
num
填充。pop
更改对象。