-1

这是一些代码:

li=[1,2,3]
def change(l):
    l[2]=10
change(li)
print li
[1, 2, 10]

但我想要这个:

li=[1,2,3]
def change(l):
    l=[1,2,10]
change(li)
print li
[1,2,3]

出于某种原因,我必须在方法中更改整个列表,我怎样才能做到这一点?有什么问题或我的错误吗?

4

5 回答 5

2

当您想更改方法中的整个列表时,您可能需要创建一个副本并返回它:

def change(li):
   new_list = li[:] #copy
   new_list[2] = 10
   return new_list

li = [1,2,3]
new_lst = change(li) #new_lst = [1,2,10]

如果不想返回列表,但想原地修改,可以使用切片赋值(*警告:这不是常见的做法):

def change(li):
    li[:] = [1,2,10]

li = [4,5,6]
change(li)
print(li) #[1, 2, 10]
于 2012-10-09T10:43:38.050 回答
1

像这样:

li = [1, 2, 3]

def change(l):
    l[:] = [1, 2, 10]

change(li)
print li  # [1, 2, 10]

您的方法不起作用的原因是在 python 中,变量只是引用对象的名称。当您编写时,l = [1, 2, 10]您正在重新绑定名称l以引用您刚刚创建的新列表,旧列表保持不变,仍然由全局变量引用li

l上面的代码改为使用slice assignment修改指向的对象。

正如 mgilson 在他的回答中指出的那样,您应该非常清楚该函数实际上就地修改了传递的参数。如果不是这样,一个毫无戒心的程序员可能会向它传递一个他打算稍后按原样使用的列表,结果却发现其中的所有内容都丢失了。给你的函数一个名称来表示修改(就像你所做的那样)并且不从它返回任何东西都是这些函数的常见指示符,例如random.shuffle.

为了对 dict 实现相同的效果,文档告诉我们这样做:

def change_dict(d):
    d.clear()  # Empty dict
    d.update({"a": 3, "b": 9})
于 2012-10-09T10:44:47.580 回答
0

当您执行以下操作时:

def change(l):
    l=[1,2,10]

您实际上正在更改哪个列表l指向。您需要将传入的列表实例更改为change. 你可以append去它,你可以pop从它,等等,你的更改将在你传入的列表中进行。如果你将你的change函数更改为我所拥有的,你的示例将起作用。

def change(l):
    l[:] = [1,2,10]
于 2012-10-09T10:48:01.663 回答
0

使用别名

文档: 列表别名 — 如何像计算机科学家一样思考(第 2

您可以利用 Python 的列表别名(这是初学者的常见问题)。

当您传递lichange函数时,的l别名li,即它们都指向内存中的同一个对象,并且更改一个对象会更改另一个对象。但是当你这样做时l = [1, 2, 10]l指向另一个列表,你就失去了混叠的魔力。要解决此问题,您可以使用切片操作替换为完整列表,如下所示:

li = [1, 2, 3]
def change(l):
    l[:] = [1, 2, 10]  # doesn't make a new list
change(li)             # preserves aliasing
print li               # returns [1, 2, 10]


使用全局变量

文档: 声明global— Python Docs

您在l函数内部所做的更改不会应用于li外部列表。您可以使用全局来影响li您尝试更改的列表:

li = [1, 2, 3]
def change():
    global li
    li = [1, 2, 10]  # use this
    li[2] = 10       # or this, up to you
change()
print li             # returns [1, 2, 10]
于 2012-10-09T10:44:08.737 回答
0

在此代码中, l 是作为整体对象的通用对象,因此您可以通过提供对象内存位置的 id() 进行检查。所以这就是为什么你得到最后一个输出 [1,2,10]

l = [1, 2, 3]
print id(l)
def change(l):
    l[:] = [1, 2, 10]
    print id(l)
change(l)
print l
print id(l)

如果你想要你想要的输出而不是使用提供不同对象的 deepcopy 来运行。

from  copy  import deepcopy
l = [1, 2, 3]
print id(l)
def change(l):
    l[:] = [1, 2, 10] 
    print id(l)
change(deepcopy(l)) 
print l
print id(l)
于 2012-10-09T11:25:42.537 回答