简体   繁体   English

Python - 实现合并排序算法时出现类型错误

[英]Python - TypeError while implementing merge sort algorithm

So I am new to python and am learning list manipulation currently.所以我是 python 的新手,目前正在学习列表操作。 Below is the program that I have written to perform a merge sort on my list.下面是我编写的用于对列表执行合并排序的程序。 However, while compiling, I get an error in line 3-但是,在编译时,我在第 3 行出现错误-

while len(lista) != 0 and len(listb) != 0:
    TypeError: object of type 'NoneType' has no len()

How can I fix this?我怎样才能解决这个问题?

def mergesort(lista, listb):
    listc = []
    while len(lista) != 0 and len(listb) != 0:
        if lista[0] > listb[0]:
            listc.append(listb[0])
            listb.remove(listb[0])
        else:
            listc.append(lista[0])
            lista.remove(lista[0])

    if len(lista) == 0:
        listc += listb
    else:
        listc += lista

    print(listc)

def merge(list):
    if len(list) == 0 or len(list) == 1:
        return list
    else:
        mid = len(list) // 2
        lista = merge(list[:mid])
        listb = merge(list[mid:])
        return mergesort(lista, listb)

list = [15, 12, 14, 17, 13, 11, 12, 16, 15]
merge(list)

Your code is confusing and flawed:您的代码令人困惑且有缺陷:

  • the sorting function is called merge and the merging function is called mergesort .排序 function 称为merge ,合并 function 称为mergesort This is exactly the opposite of any classic implementation.这与任何经典实现完全相反。

  • the merging function does not return anything, hence lista and listb get set to None from the recursive calls and mergesort applies len to arguments that are not lists.合并 function 不返回任何内容,因此listalistb从递归调用中设置为None并且mergesortlen应用于不是列表的 arguments。

Here is a modified version:这是修改后的版本:

def merge(lista, listb):
    listc = []
    while len(lista) != 0 and len(listb) != 0:
        if lista[0] > listb[0]:
            listc.append(listb[0])
            listb.remove(listb[0])
        else:
            listc.append(lista[0])
            lista.remove(lista[0])

    if len(lista) == 0:
        listc += listb
    else:
        listc += lista

    return listc

def mergesort(list):
    if len(list) < 2:
        return list
    else:
        mid = len(list) // 2
        lista = mergesort(list[:mid])
        listb = mergesort(list[mid:])
        return merge(lista, listb)

list = [15, 12, 14, 17, 13, 11, 12, 16, 15]
mergesort(list)

Firstly, don't use list as identifier.首先,不要使用list作为标识符。

In your merge function, in else block, you're returning whats being returned by mergesort function.在您的合并 function 中,在 else 块中,您将返回合并排序 function 返回的内容。 And in mergesort function, you're returning nothing.在合并排序 function 中,您什么也没有返回。

Also, due to recursion in merge function, you're ending up setting variables lista and listb to returned values of merge function which might be none since mergesort isn't returning anything(thus None).此外,由于合并 function 中的递归,您最终将变量listalistb设置为合并 function 的返回值,因为mergesort没有返回任何内容(因此没有)。

When you send those lista and listb in mergesort as arguments, you actually send None in such cases, and thus you get error when you try getting their length by len function.当您在合并排序中将这些listalistb作为 arguments 发送时,实际上在这种情况下发送 None,因此当您尝试通过len function 获取它们的长度时会出现错误。

To remove error, you can either send modified results to merge, or either can work on the list which is available in both function's scope.要消除错误,您可以将修改后的结果发送到合并,或者可以在两个函数的 scope 中可用的列表上工作。

That is because in your merge function, the lista and listb are becoming None and getting passed to the function Also your merge_sort function is not correct.这是因为在您的合并 function 中,lista 和 listb 变为 None 并传递给 function 您的 merge_sort function 也不正确。 You can handle your error by using this code below:您可以使用以下代码处理您的错误:

def mergesort(lista, listb):
    listc = []
    if not lista or not listb:
        return None
    while len(lista) != 0 and len(listb) != 0:
        if lista[0] > listb[0]:
            listc.append(listb[0])
            listb.remove(listb[0])
        else:
            listc.append(lista[0])
            lista.remove(lista[0])


    if len(lista) == 0:
        listc += listb
    else:
        listc += lista

    print(listc)

def merge(list):
    if len(list) == 0 or len(list) == 1:
        return list
    else:
        mid = len(list) // 2
        lista = merge(list[:mid])
        listb = merge(list[mid:])
        return mergesort(lista,listb)


list = [15, 12, 14, 17, 13, 11, 12, 16, 15]
merge(list)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM