python中

时间:2016-04-15 21:25:09

标签: python python-2.7 recursion typeerror

我在Python 2.7中编写了一个递归插入排序函数,遇到了两件我无法理解的事情。

第一个是错误TypeError: can only assign an 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

1 个答案:

答案 0 :(得分:0)

第一次实现的问题在于循环内的if语句。如果由于v[i-1]小于或等于v[i]而退出循环,则不会return任何内容(在Python中与执行return None相同)。您获得的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

你可能也应该把这个条件放在你的另一个版本中。

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

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

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或其他更有效的排序竞争。