python列表和快速排序,引用或指针?

时间:2014-05-02 06:32:02

标签: python list pointers reference quicksort

我是新来的蟒蛇。

最近我在python中实现了quicksort。

我听说名为list的变量类型是可变的,因此对此进行的任何更改都将生效。但是,它不在我的位置。

这是我的情况,已经测试了名为 alpartition 的函数,并且向我证明了这个函数可以工作。(因为它在快速排序算法中是必需的)。名为 test 的函数是递归函数。正如我们从打印结果中看到的那样,变量的所有方都被称为 a 。但它只是没有进来。在我看来,这个变量已经做了一个改变。

我曾经是一名C程序员,我将列表视为指针的集合,我猜错是由于切片技术的误用。

非常感谢您的帮助。

这是功能:

__author__ = 'tk'
import random
def alpartition(my_str):

    signal = 0
    i = 0
    j = len(my_str)

    while i < j:
            if signal == 0 :
                while 1:
                    j = j - 1
                    if my_str[j] <= my_str[i]:
                        break
                signal = 1
            else:
                while 1:
                    i = i + 1
                    if my_str[j] <= my_str[i]:
                        break
                signal = 0
            my_str[j],my_str[i] = my_str[i],my_str[j]
    my_str[j],my_str[i] = my_str[i],my_str[j]
    return i


def test(my_str):
    if len(my_str)>1:
        tick = alpartition(my_str)
        print my_str,my_str[0:tick:],my_str[tick+1::],tick #We can see that my_str has correctly been modified 
        if tick > 0 :
            test(my_str[0:tick:])
            test(my_str[tick+1::])
a= [86, 44, 31, 7, 9, 90, 93, 12, 59, 34]
test(a)
print a

结果如下: 要打印的第一个变量是分区变量,它由名为 tick 的变量分区,其值将打印在第四个位置。 第二个和第三个变量只是部分变量。

[34, 44, 31, 7, 9, 59, 12, 86, 93, 90] [34, 44, 31, 7, 9, 59, 12] [93, 90] 7
[12, 9, 31, 7, 34, 59, 44] [12, 9, 31, 7] [59, 44] 4
[7, 9, 12, 31] [7, 9] [31] 2
[7, 9] [] [9] 0
[44, 59] [44] [] 1
[90, 93] [90] [] 1
[34, 44, 31, 7, 9, 59, 12, 86, 93, 90]

我的问题是为什么最终结果与最初的第一个打印变量相同。为什么还没有对这个变量进行所有更改?

1 个答案:

答案 0 :(得分:0)

Python列表不可变的,但是,切片操作每次都会返回一个新列表。这就是为什么在python中获取列表的新副本的常用习惯是用[:]对其进行切片。这将返回一个新列表,其中包含旧丢失的所有项目。

然而,关于列表中元素的可变性或不变性存在一个微妙的观点。在你的情况下,因为它们是数字并且是不可变的,所以从切片返回的新列表是一个全新的列表,更改它不会影响原始列表:

>>> my_list = [1, 2, 3]        # Create a list with three numbers
>>> my_other_list = my_list[:] # Slice the original list to get a copy
>>> my_other_list[0] = 42      # Change the first element of the new list
>>> my_other_list, my_list     # See the two lists side by side
([42, 2, 3], [1, 2, 3])        # The change to the new list did not effect the original list

但是,如果第一个列表的内容属于可变类型,请说list。然后故事会有所不同:

>>> my_list = [[1], [2], [3]]
>>> my_other_list = my_list[:]
>>> my_other_list[0].append(42)
>>> my_other_list, my_list
([[1, 42], [2], [3]], [[1, 42], [2], [3]])

我只想说在你的情况下,你的列表中的元素是数字,它们是不可变的。因此,每次切片原始列表时,您都会获得一个新列表,并且您对其所做的任何更改都不会影响原始列表。