Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python中递归插入排序函数的意外行为_Python_Python 2.7_Recursion_Typeerror - Fatal编程技术网

python中递归插入排序函数的意外行为

python中递归插入排序函数的意外行为,python,python-2.7,recursion,typeerror,Python,Python 2.7,Recursion,Typeerror,我在Python2.7中编写递归插入排序函数时遇到了两件我不理解的事情 第一个是错误TypeError:只能分配一个iterable,我猜这与函数的递归有关,但我的代码没有特别的问题: def recursiveInsertionSort(v): if len(v)!=2: v[0:len(v)-1]=recursiveInsertionSort( v[0:len(v)-1]) i=len(v)-1 while v[i-1]>v[i]:

我在Python2.7中编写递归插入排序函数时遇到了两件我不理解的事情

第一个是错误
TypeError:只能分配一个iterable
,我猜这与函数的递归有关,但我的代码没有特别的问题:

def recursiveInsertionSort(v):
    if len(v)!=2:
        v[0:len(v)-1]=recursiveInsertionSort( v[0:len(v)-1])
    i=len(v)-1
    while v[i-1]>v[i]:
        v[i-1], v[i]=v[i], v[i-1]
        i-=1
        if i==0: return v
第二个问题可能是相关的

在这种情况下,我甚至没有得到一个错误(如果你知道为什么请告诉我),但功能就是不工作

def recursiveInsertionSort(v):
    if len(v)!=2:
        recursiveInsertionSort(v[0:len(v)-1])
    i=len(v)-1
    while v[i-1]>v[i] and i>0:
        v[i-1], v[i]=v[i], v[i-1]
        i-=1
当我猜问题出在递归使用函数时,我纠正了我的错误:

def recursiveInsertionSort(v):
    if len(v)!=2:
        temp=v[0:len(v)-1]
        recursiveInsertionSort( temp)
        v[0:len(v)-1]=temp
    i=len(v)-1
    while v[i-1]>v[i] and i>0:
        v[i-1], v[i]=v[i], v[i-1]
        i-=1
但我真的很想了解这两种行为的原因,你能帮我吗

编辑我还问是否有更好的方法:

temp=v[0:len(v)-1]
recursiveInsertionSort( temp)
v[0:len(v)-1]=temp

第一个实现的问题是循环中的
if
语句。如果循环退出是因为
v[i-1]
小于或等于
v[i]
,它将不会
返回任何内容(在Python中,这与执行
不返回任何内容相同)。您得到的
TypeError
来自递归调用,该调用返回
None
值,因为您无法将
None
分配给切片

如果将
while
语句中的两个条件组合在一起,并在循环结束后无条件返回
v
,则可以使代码的第一个版本工作:

while i > 0 and v[i-1] > v[i]:
    v[i-1], v[i] = v[i], v[i-1]
    i -= 1
return v
您可能也应该在其他版本中按此顺序放置条件

至于为什么你的第二个版本不起作用,问题是你正在分割原始列表,得到一个新列表,其中包含部分内容副本。然后,您的递归排序正在原地修改该副本。但是外部函数没有任何方式查看更改,因为它没有保留对切片副本的引用。您的第三个版本通过将切片显式保存为新变量来修复此问题

我认为没有更好的方法可以精确地完成上一个代码块的三行。但是,如果将函数更改为接受要排序的最高索引的可选参数,则完全可以不进行切片:

def recursiveInsertionSort(v, i=None):
    if i is None:
       i = len(v) - 1
    if i > 1:
        recursiveInsertionSort(v, i-1)
    while v[i-1]>v[i] and i>0:
        v[i-1], v[i]=v[i], v[i-1]
        i-=1

这将比您当前的代码更有效率,因为它不会为每个递归调用复制列表。不过,这两个版本仍然是
O(N**2)
,所以不要指望它能与
quicksort
或其他更有效的大数据集排序相竞争。

我没有注意到这一点,但它并不能解释“类型错误”。我想你暴露的问题在我检查它是否工作时没有出现,因为它在v[0:len(v)-1]=recursiveInsertionSort(v[0:len(v)-1])方面有问题,但我不知道为什么。
TypeError
发生在上一个递归调用中,当它试图将
None
分配给一个切片时。我已经编辑了一些内容来解释异常的来源,并建议对其他实现进行改进。