Python相同的列表被一个函数改变而不被另一个函数改变

时间:2016-07-12 22:22:27

标签: python-2.7 variables parameter-passing

我已经阅读了很多关于可变对象的修改如何反映在函数外部的SO页面,但是不可变对象(显然)不会。但是我对这段代码感到有些困惑,我将相同的列表发送到两个不同的排序函数,一个将修改它,另一个不会。

def bubbleSort(mylist):
    for i in range(len(mylist)):
            for j in range(i,len(mylist)):
                    if mylist[i] > mylist[j]:
                            mylist[i], mylist[j] = mylist[j], mylist[i]
    return mylist

上面的 bubbleSort()可以像:

一样调用
bubbleSort(mylist)

它工作得很好, mylist 的中间化反映在调用者中。您可以完全忽略调用者中 bubbleSort()的返回值。

def mergeSort(mylist):
    listSize = len(mylist)
    shortSize = int(listSize/2)
    if listSize == 1:
            return (mylist)
    mylistLeft = mergeSort(mylist[:shortSize])
    mylistRight = mergeSort(mylist[shortSize:])
    i, j = 0, 0
    result = []
    while (i < len(mylistLeft) and j < len(mylistRight)):
            if mylistLeft[i] > mylistRight[j]:
                    result.append(mylistRight[j])
                    j += 1
            else:
                    result.append(mylistLeft[i])
                    i += 1
    result += mylistRight[j:]
    result += mylistLeft[i:]
    return result

此处的 mergeSort()无法像上面的调用一样进行调用。相反,我必须称之为:

newlist = mergeSort(mylist)

并且新列表具有我想要的内容,而 mylist 包含未排序的列表。所以 bubbleSort()不需要返回语句,而 mergeSort()没有它就没用。我理解递归返回的必要性,但我希望不必在调用函数中使用返回值。

所以我的问题是,区别是什么?在这两种情况下,Aren的变量是否可变?

1 个答案:

答案 0 :(得分:1)

您的mergeSort函数根本不会修改传入的列表。它会创建一个新列表。

results = []创建一个全新的空列表。然后你要添加元素。这些都不会修改您传入的原始列表。

修改

顺便说一下,确实可以“就地”执行合并排序(通过修改原始列表而不是创建新列表),但这有点棘手。作为一种通用技术,您希望继续传递原始列表,但使用索引来标记每个递归调用应该在列表的哪个部分进行操作。