python: 在子例程中更改列表值
python: changing list value in sub-routine
我有一个简单的例子。
函数 test_list_change 应该更改作为参数传递给它的列表。
在这个函数中有一个调用子例程 test_list_change_2 应该改变相同的列表。
问题是,结果列表不包含 test_list_change_2 子例程所做的更改
为什么会这样?
示例如下:
def test_list_change(lst):
if len(lst) < 3:
lst.append("the last one")
test_list_change_2(lst)
def test_list_change_2(lst):
lst = ["the very last one"]
string_list = ["first", "another one"]
test_list_change(string_list)
print (string_list)
输出:
['first', 'another one', 'the last one']
您需要 return ["the very last one"]
在 test_list_change_2
:
def test_list_change_2():
return ["the very last one"]
并在第一个函数中将函数的结果分配给 lst
:
def test_list_change(lst):
if len(lst) < 3:
lst.append("the last one")
lst= test_list_change_2()
请注意,实际上您不需要这里的功能!!!你可以在第一个函数中做这个赋值。
您的 test_list_change2
程序正在执行 lst = ['the very last one']
。它只是将一个新对象分配给本地名称 lst
。它对传递给该过程的列表没有任何影响。
我不确定你想要完成什么。如果你想 test_list_change2
添加到 lst
,只需附加它。你能澄清一下吗?
你需要实际改变原来的list/object
:
def test_list_change(lst):
if len(lst) < 3:
lst.append("the last one")
test_list_change_2(lst)
def test_list_change_2(lst):
lst[:] = ["the very last one"] # changes original list object
string_list = ["first", "another one"]
test_list_change(string_list)
print (string_list)
['the very last one']
如果你想改变周围的元素:
def test_list_change_2(lst):
lst[:-1] = ["the very last one"]
lst[:] = lst[::-1]
string_list = ["first", "another one"]
test_list_change(string_list)
print (string_list)
['the last one', 'the very last one']
您可以随心所欲地操作列表,但您需要实际引用原始列表对象,重新分配名称不会更改 lst,它只会将该名称分配给另一个对象。
如果您只想 "the very last one" 出现在列表中,那么:
def test_list_change(lst):
if len(lst) < 3:
lst.append("the last one")
lst = test_list_change_2(lst)
def test_list_change_2(lst):
for i in range(len(lst)):
lst.pop()
lst.append("the very last one")
string_list = ["first", "another one"]
test_list_change(string_list)
print (string_list)
您可能对 python 和 "passing by reference" 的工作方式感到困惑,并认为既然它是通过引用传递的,那么原始列表应该更新为 ["the very last one"]。
它的工作方式如下:
1) 在 test_list_change 被调用之前,有一个名字 "string_list" 和 python 创建一个对象 ["first", "another one"] 被赋值至 string_list
2) 现在在 test_list_change 中,新名称 "lst" 被分配 ["first"、"another one"]。所以现在两个名字都分配了同一个对象。然后附加并更改为 ['first'、'another one'、'the last one'],由 string_list 和 lst
指向
3) 在test_list_change_2中,在赋值之前,存在另一个指向["first"、"another one"、'ths last one']的本地lst name。然后 python 创建另一个对象 ['the vary last one'] 并替换本地 lst 变量的值。
4) string_list 仍然指向 ['first', 'another one', 'the last one']
换句话说,变量只是传递的名称,对象是管理的 'by reference'。
我有一个简单的例子。 函数 test_list_change 应该更改作为参数传递给它的列表。 在这个函数中有一个调用子例程 test_list_change_2 应该改变相同的列表。
问题是,结果列表不包含 test_list_change_2 子例程所做的更改
为什么会这样?
示例如下:
def test_list_change(lst):
if len(lst) < 3:
lst.append("the last one")
test_list_change_2(lst)
def test_list_change_2(lst):
lst = ["the very last one"]
string_list = ["first", "another one"]
test_list_change(string_list)
print (string_list)
输出:
['first', 'another one', 'the last one']
您需要 return ["the very last one"]
在 test_list_change_2
:
def test_list_change_2():
return ["the very last one"]
并在第一个函数中将函数的结果分配给 lst
:
def test_list_change(lst):
if len(lst) < 3:
lst.append("the last one")
lst= test_list_change_2()
请注意,实际上您不需要这里的功能!!!你可以在第一个函数中做这个赋值。
您的 test_list_change2
程序正在执行 lst = ['the very last one']
。它只是将一个新对象分配给本地名称 lst
。它对传递给该过程的列表没有任何影响。
我不确定你想要完成什么。如果你想 test_list_change2
添加到 lst
,只需附加它。你能澄清一下吗?
你需要实际改变原来的list/object
:
def test_list_change(lst):
if len(lst) < 3:
lst.append("the last one")
test_list_change_2(lst)
def test_list_change_2(lst):
lst[:] = ["the very last one"] # changes original list object
string_list = ["first", "another one"]
test_list_change(string_list)
print (string_list)
['the very last one']
如果你想改变周围的元素:
def test_list_change_2(lst):
lst[:-1] = ["the very last one"]
lst[:] = lst[::-1]
string_list = ["first", "another one"]
test_list_change(string_list)
print (string_list)
['the last one', 'the very last one']
您可以随心所欲地操作列表,但您需要实际引用原始列表对象,重新分配名称不会更改 lst,它只会将该名称分配给另一个对象。
如果您只想 "the very last one" 出现在列表中,那么:
def test_list_change(lst):
if len(lst) < 3:
lst.append("the last one")
lst = test_list_change_2(lst)
def test_list_change_2(lst):
for i in range(len(lst)):
lst.pop()
lst.append("the very last one")
string_list = ["first", "another one"]
test_list_change(string_list)
print (string_list)
您可能对 python 和 "passing by reference" 的工作方式感到困惑,并认为既然它是通过引用传递的,那么原始列表应该更新为 ["the very last one"]。
它的工作方式如下:
1) 在 test_list_change 被调用之前,有一个名字 "string_list" 和 python 创建一个对象 ["first", "another one"] 被赋值至 string_list
2) 现在在 test_list_change 中,新名称 "lst" 被分配 ["first"、"another one"]。所以现在两个名字都分配了同一个对象。然后附加并更改为 ['first'、'another one'、'the last one'],由 string_list 和 lst
指向3) 在test_list_change_2中,在赋值之前,存在另一个指向["first"、"another one"、'ths last one']的本地lst name。然后 python 创建另一个对象 ['the vary last one'] 并替换本地 lst 变量的值。
4) string_list 仍然指向 ['first', 'another one', 'the last one']
换句话说,变量只是传递的名称,对象是管理的 'by reference'。