函数在Python中更改列表值而不是变量值 [英] Function changes list values and not variable values in Python

查看:88
本文介绍了函数在Python中更改列表值而不是变量值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我们来看一个简单的代码:

  y = [1,2,3] 

def len(y):
for x in range(len(y)):
y [x] + = 1
return y

print plusOne(y) ,y


a = 2

def plusOne2(a):
a + = 1
返回a

打印plusOne2(a),a

'y'的值发生了变化,但'a'的值保持不变相同。我已经知道这是因为一个是可变的,另一个不是。但如何更改代码,以便函数不会改变列表?



例如,要做类似的事情(为了简单起见,使用伪代码):


$ b $

  a = [1,2,3,...,n] 

函数doSomething(x):
做x
的东西返回x

b = doSomething(a)

如果someOperation(a)> someOperation(b):
做的东西

编辑:对不起,但我有嵌套列表中的另一个问题。看这段代码:

  def change(y):
yN = y [:]
for i在范围内(len(yN)):
如果yN [i] [0] == 1:
yN [i] [0] = 0
else:
yN [ i] [0] = 1
返回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 [:] 例如(正如其他人指出的那样)。或者,如果以这种方式调用该函数可能有用,那么如果他想要 ,可以让 caller 传入 x [:]复制。

Let's take a simple code:

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

Values of 'y' change but value 'a' stays the same. I have already learned that it's because one is mutable and the other is not. But how to change the code so that the function doesn't change the list?

For example to do something like that (in pseudocode for simplicity):

a = [1,2,3,...,n]

function doSomething(x):
    do stuff with x
    return x

b = doSomething(a)

if someOperation(a) > someOperation(b):
    do stuff

EDIT: Sorry, but I have another question on nested lists. See this code:

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)

Here it doesn't work. Why? Again: how to avoid this problem? I understand why it is not working: yN = y[:] copies values of y to yN, but the values are also lists, so the operation would have to be doubled for every list in list. How to do this operation with nested lists?

解决方案

Python variables contain pointers, or references, to objects. All values (even integers) are objects, and assignment changes the variable to point to a different object. It does not store a new value in the variable, it changes the variable to refer or point to a different object. For this reason many people say that Python doesn't have "variables," it has "names," and the = operation doesn't "assign a value to a variable," but rather "binds a name to an object."

In plusOne you are modifying (or "mutating") the contents of y but never change what y itself refers to. It stays pointing to the same list, the one you passed in to the function. The global variable y and the local variable y refer to the same list, so the changes are visible using either variable. Since you changed the contents of the object that was passed in, there is actually no reason to return y (in fact, returning None is what Python itself does for operations like this that modify a list "in place" -- values are returned by operations that create new objects rather than mutating existing ones).

In plusOne2 you are changing the local variable a to refer to a different integer object, 3. ("Binding the name a to the object 3.") The global variable a is not changed by this and continues to point to 2.

If you don't want to change a list passed in, make a copy of it and change that. Then your function should return the new list since it's one of those operations that creates a new object, and the new object will be lost if you don't return it. You can do this as the first line of the function: x = x[:] for example (as others have pointed out). Or, if it might be useful to have the function called either way, you can have the caller pass in x[:] if he wants a copy made.

这篇关于函数在Python中更改列表值而不是变量值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆