Tim*_*Tim 5 python variables function list nested-lists
我们来看一个简单的代码:
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
Run Code Online (Sandbox Code Playgroud)
'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
Run Code Online (Sandbox Code Playgroud)
编辑:抱歉,我在嵌套列表上有另一个问题.看到这段代码:
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)
Run Code Online (Sandbox Code Playgroud)
在这里它不起作用.为什么?再说一遍:如何避免这个问题?我理解为什么它不起作用:yN = y [:]将y的值复制到yN,但值也是列表,因此对于列表中的每个列表,操作必须加倍.如何使用嵌套列表执行此操作?
kin*_*all 15
Python变量包含对象的指针或引用.所有值(甚至整数)都是对象,赋值将变量更改为指向不同的对象.它不会在变量中存储新值,它会更改变量以引用或指向其他对象.出于这个原因,许多人说Python没有"变量",它有"名称",=操作不"为变量赋值",而是"将名称绑定到对象".
在plusOne您要修改(或"突变")的内容的y,但从来没有改变什么y本身指.它保持指向同一个列表,即传递给函数的列表.全局变量y和局部变量y引用相同的列表,因此使用任一变量都可以看到更改.由于您更改了传入的对象的内容,因此实际上没有理由返回y(实际上,返回None是Python本身对此类操作所做的操作,即"就地"修改列表 - 值由操作返回创建新对象而不是改变现有对象.
在plusOne2您正在更改局部变量a以引用不同的整数对象,3.("将名称绑定a到对象3.")全局变量a不会被此更改并继续指向2.
如果您不想更改传入的列表,请复制它并更改它.然后你的函数应该返回新的列表,因为它是创建新对象的那些操作之一,如果你不返回它,新对象将会丢失.您可以将此作为函数的第一行:x = x[:]例如(正如其他人指出的那样).或者,如果以任一方式调用该函数可能有用,则可以让调用者传入,x[:]如果他想要复制.
创建列表的副本.用testList = inputList[:].看代码
>>> def plusOne(y):
newY = y[:]
for x in range(len(newY)):
newY[x] += 1
return newY
>>> y = [1, 2, 3]
>>> print plusOne(y), y
[2, 3, 4] [1, 2, 3]
Run Code Online (Sandbox Code Playgroud)
或者,您可以在函数中创建新列表
>>> def plusOne(y):
newList = []
for elem in y:
newList.append(elem+1)
return newList
Run Code Online (Sandbox Code Playgroud)
您也可以像其他人指出的那样使用理解.
>>> def plusOne(y):
return [elem+1 for elem in y]
Run Code Online (Sandbox Code Playgroud)