python - python中通过引用传递

标签 python

据我所知,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/

相关文章:

python - 在 Tornado 项目中验证表单数据的最佳方法?

python - Django 多重继承 E005

python - 确保测试用例可以删除它创建的临时目录

python - 如何避免此 "' 元组'对象没有属性 'photo'“我的自定义用户模块中的错误?

python - 当目标字符串包含在列表中时,str.replace 似乎无法正常运行

python - 为什么 __slots__ 不是 Python 中的默认值?

python - 队列对象只能通过继承在进程之间共享

python - Python 中的 MySQL 提示占位符

python - Azure 应用服务上的 Python 本地日志在哪里?

python - Scikit Learn - 组合 TfidfVectorizer 和 OneHotEncoder 的输出 - 维度