【问题标题】:Merge two sorted lists合并两个排序列表
【发布时间】:2015-05-12 10:44:18
【问题描述】:

你好我想问一下为什么当我在arr下面运行这段代码时没有改变它的值

def merge(arr, left, middle, right):
    newArr = []
    leftCounter = 0
    rightCounter = middle + 1
    while leftCounter <= middle and rightCounter <= right:
        if arr[leftCounter] < arr[rightCounter]:
            newArr.append(arr[leftCounter])
            leftCounter += 1
        else:
            newArr.append(arr[rightCounter])
            rightCounter += 1
    while leftCounter <= middle:
        newArr.append(arr[leftCounter])
        leftCounter += 1
    while rightCounter <= right:
        newArrCounter.append(arr[rightCounter])
        rightCounter += 1
    arr = newArr



def main():
    arr = [1, 5, 7, 2, 4, 6]
    merge(arr, 0, 2, 5)
    print(arr)

这个结果是 [1, 5, 7, 2, 4, 6]

谢谢

【问题讨论】:

  • 为了记录,这个函数是标准库的一部分,如heapq.merge()

标签: python list merge


【解决方案1】:

简单地说,当您将arr 传递给函数时,它正在引用内存中的一个列表,但它与函数外部的arr 的引用不同(即使它们引用了同一个对象)。在函数中,当你有

arr = newArr

基本上你有指向新对象的函数范围引用,但没有函数外部的引用。

http://robertheaton.com/2014/02/09/pythons-pass-by-object-reference-as-explained-by-philip-k-dick/

如果您在函数内变异 arr,由于它们引用同一个对象,函数外部的引用仍将引用变异对象。

【讨论】:

    【解决方案2】:

    由于函数内部的变量具有局部作用域。您可以在函数中返回arr并将函数结果分配给变量,在函数的尾部添加return arr

    def main():
        arr = [1, 5, 7, 2, 4, 6]
        new=merge(arr, 0, 2, 5)
        print(new)
    

    但是注意,改变函数内部的可变对象可能会影响调用者!但在这种情况下,您在末尾分配了newArr arr arr = newArr,然后您不更改 arr,例如,请参见以下示例:

    >>> def a(arr):
    ...   arr = [3,4]
    >>> x=[5]
    >>> a(x)
    >>> x
    [5]
    >>> def a(arr):
    ...   arr+= [3,4]
    ... 
    >>> a(x)
    >>> x
    [5, 3, 4]
    

    在第一个状态下,我们已经分配了一个新对象命名为arr,因此python 将在函数a 的本地命名空间中创建一个局部变量!但是在第二种情况下,我们更改了名称arr,并且arr 是一个可变对象,python 不会创建新对象,而是全局更改名称arr

    或者您可以将newArr 初始化为全局,然后您可以在主函数中打印它:

    def merge(arr, left, middle, right):
        global newArr
        newArr = []
        leftCounter = 0
        rightCounter = middle + 1
        while leftCounter <= middle and rightCounter <= right:
            if arr[leftCounter] < arr[rightCounter]:
                newArr.append(arr[leftCounter])
                leftCounter += 1
            else:
                newArr.append(arr[rightCounter])
                rightCounter += 1
        while leftCounter <= middle:
            newArr.append(arr[leftCounter])
            leftCounter += 1
        while rightCounter <= right:
            newArrCounter.append(arr[rightCounter])
            rightCounter += 1
        arr = newArr
    
    def main():
        arr = [1, 5, 7, 2, 4, 6]
        merge(arr, 0, 2, 5)
        print(newArr)
    

    【讨论】:

    • 但是当我尝试在合并函数中执行此 arr[3] = 5 时,arr 会全局更改,为什么?你的代码是错误的函数没有返回任何东西!
    • @user3216932 的区别在于arr 是一个可变对象,更改函数内部的可变对象可能会影响调用者!
    • 我不能把它变成 = newArr 吗?
    • @user3216932 你可以使用global 关键字!或return
    猜你喜欢
    • 1970-01-01
    • 2022-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-16
    • 2016-03-30
    • 2012-10-31
    • 2021-10-06
    相关资源
    最近更新 更多