函数更改列表值而不是Python中的变量值
作者:互联网
参见英文答案 > Why can a function modify some arguments as perceived by the caller, but not others? 10个
我们来看一个简单的代码:
y = [1,2,3]
def plusOne(y):
for x in range(len(y)):
y[x] += 1
return y
print plusOne(y), y
a = 2
def plusOne2(a):
a += 1
return a
print plusOne2(a), a
‘y’的值发生变化但值’a’保持不变.我已经知道这是因为一个是可变的而另一个不是.但是如何更改代码以使函数不更改列表?
例如,要做类似的事情(为了简单起见,使用伪代码):
a = [1,2,3,...,n]
function doSomething(x):
do stuff with x
return x
b = doSomething(a)
if someOperation(a) > someOperation(b):
do stuff
编辑:抱歉,我在嵌套列表上有另一个问题.看到这段代码:
def change(y):
yN = y[:]
for i in range(len(yN)):
if yN[i][0] == 1:
yN[i][0] = 0
else:
yN[i][0] = 1
return yN
data1 = [[1],[1],[0],[0]]
data2 = change(data1)
在这里它不起作用.为什么?再说一遍:如何避免这个问题?我理解为什么它不起作用:yN = y [:]将y的值复制到yN,但值也是列表,因此对于列表中的每个列表,操作必须加倍.如何使用嵌套列表执行此操作?
解决方法:
Python变量包含对象的指针或引用.所有值(甚至整数)都是对象,赋值将变量更改为指向不同的对象.它不会在变量中存储新值,它会更改变量以引用或指向其他对象.出于这个原因,许多人说Python没有“变量”,它有“名称”,而=操作不“为变量赋值”,而是“将名称绑定到对象”.
在plusOne中,您正在修改(或“改变”)y的内容,但永远不会改变y本身所指的内容.它保持指向同一个列表,即传递给函数的列表.全局变量y和局部变量y引用相同的列表,因此使用任一变量都可以看到更改.由于您更改了传入的对象的内容,因此实际上没有理由返回y(实际上,返回None是Python本身对此类操作所做的操作,即“就地”修改列表 – 值返回创建新对象而不是改变现有对象的操作.
在plusOne2中,您正在更改局部变量a以引用不同的整数对象,3.(“将名称a绑定到对象3”.)全局变量a不会被此更改并继续指向2.
如果您不想更改传入的列表,请复制它并更改它.然后你的函数应该返回新的列表,因为它是创建新对象的那些操作之一,如果你不返回它,新对象将会丢失.您可以将此作为函数的第一行:x = x [:]例如(正如其他人指出的那样).或者,如果以任一方式调用该函数可能有用,则可以让调用者在x [:]中传递,如果他想要复制的话.
标签:nested-lists,python,variables,function,list 来源: https://codeday.me/bug/20190915/1806483.html