如何通过引用传递列表?
How to pass a list by reference?
我正在尝试实现一个函数 'add',它将列表 L1
与 L2
合并为 L3
:
def add(L1,L2,L3):
L3 = L1 + L2
L3 = []
add([1],[0],L3)
print L3
上面的代码生成了一个空列表而不是 [1,0]
- 这意味着 L3
没有通过引用传递。
如何通过引用传递L3
?
您可以通过以下方式实现:
L3[:] = L1 + L2
测试代码:
def add(L1, L2, L3):
L3[:] = L1 + L2
L3 = []
add([1], [0], L3)
print(L3)
结果:
[1, 0]
如果您想就地进行更改,则需要执行修改列表的操作就地。这意味着任何 list
实例方法。在此特定实例中,您可以查看 list.extend
.
def add(L1, L2, L3):
L3.extend(L1 + L2) # creates a new list object and copies it into L3
由于这会创建一个副本(这可能效率低下),您可以代替在其位置使用两个 extend
调用 -
def add(L1, L2, L3):
L3.extend(L1)
L3.extend(L2)
调用L3.extend
就地修改原始列表。使用您当前的代码,L1 + L2
创建一个新列表,并将 L3
重新分配给该对象(并且未触及 L3
所指的原始对象)。
如果您想将其推广到任意数量的列表,我建议您查看使用可变参数:
from itertools import chain
def add(L3, *L):
L3.extend(chain.from_iterable(L))
这是它如何工作的一个例子:
>>> L3 = []
>>> add(L3, [1], [2], [3])
>>> L3
[1, 2, 3]
作为一种良好做法,您应该
- 定义一个不修改原始结构的函数,但returns一个你可以从调用者分配的新值,或者
- 定义一个修改结构的函数,returns什么都不做。
另一个用户注意事项:L3[:] = ...
将 将其所有以前的内容 L3
替换为 L1 + L2
中的项目。另一方面,L3.extend(...)
不会破坏之前在 L3
中的内容,而是通过传递的内容 扩展 。我建议评估您的用例并根据情况使用更合适的方法。
但是,为了迎合这种情况,您可以使用 __setitem__
:
就地赋值来构建已接受答案的方法
def add(L3, *L):
L3[:] = chain.from_iterable(L)
其工作方式相同,并且对于许多列表应该非常有效。
列表已经通过引用传递,因为 all Python 名称是引用,列表对象是可变的。使用切片分配而不是正常分配。
def add(L1, L2, L3):
L3[:] = L1 + L2
但是,这不是编写函数的好方法。您应该 return 组合列表。
def add(L1, L2):
return L1 + L2
L3 = add(L1, L2)
您不能在 Python 中通过引用显式传递变量,但您可以更新现有对象的属性。
因此,您可以做的是更新 L3
上的值,所有这些都适合您的情况,因此您可以这样做:
def add(L1 ,L2, L3):
L3[:] = L1 + L2
L3 = []
add([1], [0], L3)
print L3
我正在尝试实现一个函数 'add',它将列表 L1
与 L2
合并为 L3
:
def add(L1,L2,L3):
L3 = L1 + L2
L3 = []
add([1],[0],L3)
print L3
上面的代码生成了一个空列表而不是 [1,0]
- 这意味着 L3
没有通过引用传递。
如何通过引用传递L3
?
您可以通过以下方式实现:
L3[:] = L1 + L2
测试代码:
def add(L1, L2, L3):
L3[:] = L1 + L2
L3 = []
add([1], [0], L3)
print(L3)
结果:
[1, 0]
如果您想就地进行更改,则需要执行修改列表的操作就地。这意味着任何 list
实例方法。在此特定实例中,您可以查看 list.extend
.
def add(L1, L2, L3):
L3.extend(L1 + L2) # creates a new list object and copies it into L3
由于这会创建一个副本(这可能效率低下),您可以代替在其位置使用两个 extend
调用 -
def add(L1, L2, L3):
L3.extend(L1)
L3.extend(L2)
调用L3.extend
就地修改原始列表。使用您当前的代码,L1 + L2
创建一个新列表,并将 L3
重新分配给该对象(并且未触及 L3
所指的原始对象)。
如果您想将其推广到任意数量的列表,我建议您查看使用可变参数:
from itertools import chain
def add(L3, *L):
L3.extend(chain.from_iterable(L))
这是它如何工作的一个例子:
>>> L3 = []
>>> add(L3, [1], [2], [3])
>>> L3
[1, 2, 3]
作为一种良好做法,您应该
- 定义一个不修改原始结构的函数,但returns一个你可以从调用者分配的新值,或者
- 定义一个修改结构的函数,returns什么都不做。
另一个用户注意事项:L3[:] = ...
将 将其所有以前的内容 L3
替换为 L1 + L2
中的项目。另一方面,L3.extend(...)
不会破坏之前在 L3
中的内容,而是通过传递的内容 扩展 。我建议评估您的用例并根据情况使用更合适的方法。
但是,为了迎合这种情况,您可以使用 __setitem__
:
def add(L3, *L):
L3[:] = chain.from_iterable(L)
其工作方式相同,并且对于许多列表应该非常有效。
列表已经通过引用传递,因为 all Python 名称是引用,列表对象是可变的。使用切片分配而不是正常分配。
def add(L1, L2, L3):
L3[:] = L1 + L2
但是,这不是编写函数的好方法。您应该 return 组合列表。
def add(L1, L2):
return L1 + L2
L3 = add(L1, L2)
您不能在 Python 中通过引用显式传递变量,但您可以更新现有对象的属性。
因此,您可以做的是更新 L3
上的值,所有这些都适合您的情况,因此您可以这样做:
def add(L1 ,L2, L3):
L3[:] = L1 + L2
L3 = []
add([1], [0], L3)
print L3