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

编程入门 行业动态 更新时间:2024-10-28 16:23:05
函数在Python中更改列表值而不是变量值(Function changes list values and not variable values in Python [duplicate])

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

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,但值也是列表,因此对于列表中的每个列表,操作必须加倍。 如何使用嵌套列表执行此操作?

This question already has an answer here:

Why can a function modify some arguments as perceived by the caller, but not others? 10 answers

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变量包含指向对象的指针或引用。 所有值(即使是整数)都是对象,并且赋值会将变量更改为指向不同的对象。 它不会变量中存储新值,它会更改变量以引用或指向其他对象。 出于这个原因,很多人说Python没有“变量”,它有“名称”,而=操作不会“为变量赋值”,而是“将名称绑定到对象”。

在plusOne您正在修改(或“改变”) y的内容 ,但不会更改y本身引用的内容。 它保持指向同一个列表,即你传递给函数的列表。 全局变量y和局部变量y引用相同的列表,所以使用任何变量都可以看到更改。 由于您更改了传入的对象的内容,因此实际上没有理由返回y (事实上​​,返回None是Python本身为像这样的操作修改列表的“就地”操作 - 值将返回创建新对象而不是改变现有对象的操作)。

在plusOne2您正在更改局部变量a以引用不同的整数对象3 。 (“将名称a绑定到对象3 ”)全局变量a不会因此而改变,并继续指向2 。

如果您不想更改传入的列表,请复制并更改该列表。 然后你的函数应该返回新的列表,因为它是创建一个新对象的操作之一,如果你不返回它,新对象将会丢失。 您可以将其作为函数的第一行:例如x = x[:] (正如其他人指出的那样)。 或者,如果以这种方式调用该函数可能有用,则可以让调用者在x[:]传递,如果他想要复制的话。

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.

更多推荐

本文发布于:2023-07-22 18:17:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1222261.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:函数   而不是   变量值   列表   Python

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!