【问题标题】:python list and quick sort, reference or pointer?python列表和快速排序、引用还是指针?
【发布时间】:2014-05-02 06:32:01
【问题描述】:

我是python新手。

最近我在 python 中实现快速排序。

我听说名为 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

结果如下: 要打印的first变量是分区变量,它由名为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]

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

【问题讨论】:

  • 第一件事:你真的需要实现快速排序吗?真正的问题。有时新人会重新发明轮子。
  • 是的,这是我的作业,我今年正在学习算法课程。但是老师给我的代码都是伪代码。而且我正在一一做,大家可以看我的blog

标签: python list pointers reference quicksort


【解决方案1】:

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]])

只要说在您的情况下,列表的元素是数字并且它们是不可变的就足够了。因此,每次对原始列表进行切片时,都会得到一个新列表,并且对它所做的任何更改都不会影响原始列表。

【讨论】:

  • 嗨,有什么办法可以修改这段代码吗?我尝试了返回技术,但它也不起作用。
  • 哇,非常感谢你,我会把你的话记在笔记里:)
  • 现在我修好了..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 if tick > 0 : my_str[0:tick:]=test(my_str[0:tick:]) my_str[tick+1::]=test(my_str[tick+1::]) return my_str .我认为 python 列表让我很困惑,这是否也适用于我之前称为合并排序的示例。它们都属于分而治之的技术,递归对它们来说似乎是必须的。
  • @s16h 您可能想要更改:“但是,如果第一个列表的内容是不可变类型,则说是一个列表。”到“但是,如果第一个列表的内容是可变类型,则说是一个列表。”
猜你喜欢
  • 1970-01-01
  • 2020-06-05
  • 2019-11-05
  • 2017-02-27
  • 2012-05-24
  • 2014-01-08
  • 1970-01-01
  • 2021-07-14
  • 2021-01-11
相关资源
最近更新 更多