据我所知,python 传递参数作为引用。我有以下代码
def func(arr):
print(arr)
if arr == [] :
return
for i in range(len(arr)):
arr[i] *= 2
func(arr[1:])
r = [1,1,1,1]
func(r)
print(r)
我期望输出为 [2,4,8,16]。
为什么它输出 [2,2,2,2] 就好像引用仅适用于一级递归?
也许“arr[1:]”总是创建一个新对象?如果是这样的话,有什么方法可以让 arr[1:] 工作吗?
最佳答案
您提出了几个不同的问题,让我们一一讨论。
As far as I know, python passes parameter as reference.
Python 如何传递参数的正确术语是 "pass py assignment" 。这意味着函数内的参数的行为与直接用 =
符号分配的情况类似。 (因此,突变将反射(reflect)对该对象的所有引用。到目前为止一切顺利)
旁注(如果这令人困惑,请跳过):出于所有意图和目的,“按赋值传递”的区别很重要,因为它抽象了按值传递和按引用传递,这些概念在 python 中不直接公开。如果您想知道底层机制是如何工作的,它实际上是按值传递,但是每个值本身都是对对象的引用(相当于C 说话)。我们可以明白为什么一开始就不用担心这个特定的抽象,并使用“通过赋值传递”作为更直观的解释,这更容易也更重要。
下一步,
maybe 'arr[1:]' always creates a new object?
正确,切片总是创建列表的浅拷贝。 docs
If that is the case, is there any way to make arr[1:] work?
不能直接使用,但我们可以使用索引来构建一个可行的解决方案,并为我们提供您想要的输出。只需在执行递归时跟踪起始索引,并在继续递归时递增它。
def func(arr, start=0):
print(arr)
if arr[start:] == [] :
return
for i in range(start, len(arr)):
arr[i] *= 2
func(arr, start + 1)
r = [1,1,1,1]
func(r)
print(r)
输出:
[1, 1, 1, 1]
[2, 2, 2, 2]
[2, 4, 4, 4]
[2, 4, 8, 8]
[2, 4, 8, 16]
[2, 4, 8, 16]
关于python - python中通过引用传递,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59746166/