【问题标题】:TypeError: object has nonetype' len() and stops iterationTypeError: object has nonetype' len() 并停止迭代
【发布时间】:2020-08-28 00:59:45
【问题描述】:

我正在尝试运行以下代码,但它在“右侧:无”之后打印错误, 当它应该说“右侧:[2,4]”时

data =  [9,5,7,4,2,8,1,10,6,3]

def mergeSort(list):
    if len(list) < 2:
        return list
    
    middle = len(list)//2 
    
    #Break the list in 2 pieces
    left = mergeSort(list[:middle])
    right = mergeSort(list[middle:])
    
    print("Left side: ", left)
    print("Right side: ", right)
    
    
    merged = merge(left, right)
    print("Merged", merged)
    return merged
    
def merge(left,right):

    if not len(left):
        return left
    if not len(right):
        return right 

    result = []
    leftIndex = 0
    rightIndex = 0 
    totalLen = len(left) + len(right)


    while (len(result) < totalLen):
        if left[leftIndex] < right[rightIndex]:
            result.append(left[leftIndex])
            leftIndex+= 1
        else: 
            result.append(right[rightIndex])
            rightIndex+= 1 
      
        if leftIndex == len(left) or \
            rightIndex == len(right):
                result.extend(left[leftIndex:]
                             or right[rightIndex:])
                break
        return result
        
mergeSort(data)

代码在前几次迭代中有效,但停止并给出错误类型:'NoneType' has no len()。

追溯

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-66-50291ed7231f> in <module>
     47         return result
     48 
---> 49 mergeSort(data)

<ipython-input-66-50291ed7231f> in mergeSort(list)
      8 
      9     #Break the list in 2 pieces
---> 10     left = mergeSort(list[:middle])
     11     right = mergeSort(list[middle:])
     12 

<ipython-input-66-50291ed7231f> in mergeSort(list)
      9     #Break the list in 2 pieces
     10     left = mergeSort(list[:middle])
---> 11     right = mergeSort(list[middle:])
     12 
     13     print("Left side: ", left)

<ipython-input-66-50291ed7231f> in mergeSort(list)
     15 
     16 
---> 17     merged = merge(left, right)
     18     print("Merged", merged)
     19     return merged

<ipython-input-66-50291ed7231f> in merge(left, right)
     23     if not len(left):
     24         return left
---> 25     if not len(right):
     26         return right
     27 

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

【问题讨论】:

  • 如果在merge()中执行break语句,它永远不会执行return result,所以merge()默认返回None。也许return result 不应该在while 循环中?
  • 当前错误是由if not len(left)if not len(right) 引起的。将它们分别更改为if not leftif not right。如果leftright 是一个空列表,这些会捕获。
  • 你做过调试吗?我建议阅读ericlippert.com/2014/03/05/how-to-debug-small-programs。请参阅How to Askhelp center
  • 谢谢。我尝试在循环之外缩进“返回结果”并且它起作用了。!

标签: python nonetype


【解决方案1】:

尝试将您的合并功能更改为此

def merge(left, right):
    result = []
    for elem in left:
        if elem < right[0]:
            result.append(elem)
        else:
            result.append(right.pop(0))
    return result + right

【讨论】:

  • 如果我没记错的话,如果列表很大,这会很慢:right.pop(0)。 Python 列表没有针对左侧弹出很好地优化:它需要数据复制。我认为deque 模块的编写部分考虑了这个用例。
【解决方案2】:

您在mergeSort() 中有一些诊断打印,但问题在merge() 中。

    if not len(left):
        return left                # Should be right.
    if not len(right):
        return right               # Should be left.

    while (len(result) < totalLen):
        if ...
            ...
        else ...
            ...
        if ...
            ...
            break
        return result              # Should be outside the while loop.
        

【讨论】:

    猜你喜欢
    • 2021-10-05
    • 1970-01-01
    • 2022-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多