简体   繁体   中英

Python - TypeError while implementing merge sort algorithm

So I am new to python and am learning list manipulation currently. 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-

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 . 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.

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.

In your merge function, in else block, you're returning whats being returned by mergesort function. And in mergesort function, you're returning nothing.

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

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.

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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