简体   繁体   中英

TypeError: object of type 'NoneType' has no len()

I am attempting a mergesort algorithm and I am receiving this type error:

Input #1: [3, 1, 2, 5, 9, 6, 7]
Traceback (most recent call last):
  File "Lab1.py", line 24, in <module>
    print('Output #1: ' + mergesort(a))
  File "Lab1.py", line 18, in mergesort
    left = mergesort(lst[:middle])
  File "Lab1.py", line 20, in mergesort
    return merge(left, right)
  File "Lab1.py", line 6, in merge
    while i < len(left) and j < len(right):
TypeError: object of type 'NoneType' has no len()

... on this code:

def merge(left, right):
    result = []
    i, j = 0, 0
    while i < len(left) and j < len(right):
        if left[i] <= right[j]:
            result.append(left[i])
            i += 1
        else:
            result.append(right[j])
            j += 1

def mergesort(lst):
    if len(lst) <= 1:
        return lst
    middle = int(len(lst) / 2)
    left = mergesort(lst[:middle])
    right = mergesort(lst[middle:])
    return merge(left, right)

a = [3,1,2,5,9,6,7]
print 'Input #1: ' + str(a)
print 'Output #1: ' + mergesort(a)

You forget the return in your merge function:

def merge(left, right):
    result = []
    i, j = 0, 0
    while i < len(left) and j < len(right):
        if left[i] <= right[j]:
            result.append(left[i])
            i += 1
        else:
            result.append(right[j])
            j += 1
    return result

Note that this merge function is incorrect. If left and right have different lengths then result will not contain all the elements of both lists. (because one of the indices, say i , will fail the condition of i < len(left) when j didn't scan the whole right list). This will always happen, since the while loop increases only one index at a time, which means that at some point you can have i = len(left) - 1 and j = len(right) - 1 but only one of i and j will be incremented in the next iteration, and one of the two conditions will be False , causing the loop to stop.

See:

In [2]: mergesort(list(range(17)))
Out[2]: [0]

Adding:

result.extend(left[i:] or right[j:])

before the return should fix this problem:

In [4]: mergesort(list(range(17)))
Out[4]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]

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