【问题标题】:Python - TypeError while implementing merge sort algorithmPython - 实现合并排序算法时出现类型错误
【发布时间】:2020-05-01 12:33:19
【问题描述】:

所以我是 python 新手,目前正在学习列表操作。下面是我编写的用于对列表执行合并排序的程序。但是,在编译时,我在第 3 行出现错误-

而 len(lista) != 0 和 len(listb) != 0: TypeError:“NoneType”类型的对象没有 len()

我该如何解决这个问题?

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)

【问题讨论】:

    标签: python algorithm mergesort


    【解决方案1】:

    您的代码令人困惑且有缺陷:

    • 排序函数称为merge,合并函数称为mergesort。这与任何经典实现完全相反。

    • 合并函数不返回任何内容,因此 listalistb 从递归调用中设置为 Nonemergesortlen 应用于非列表的参数。

    这是修改后的版本:

    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)
    

    【讨论】:

    • 感谢它现在的工作。我后来在合并函数中使用了 return 语句,但是缩进是错误的,但现在工作顺利
    • @zsasz:python 的结构由缩进定义的风格代价高昂:它使代码非常脆弱(容易破坏)。
    【解决方案2】:

    首先,不要使用list 作为标识符。

    在您的合并函数中,在 else 块中,您返回的是合并排序函数返回的内容。而在合并排序函数中,您什么也没有返回。

    此外,由于合并函数中的递归,您最终将变量 listalistb 设置为合并函数的返回值,因为 mergesort 没有返回任何内容(因此没有)。

    当您在合并排序中发送 listalistb 作为参数时,实际上在这种情况下发送 None,因此当您尝试通过 len 函数获取它们的长度时会出错。

    要消除错误,您可以将修改后的结果发送到合并,或者可以在两个函数范围内都可用的列表上工作。

    【讨论】:

      【解决方案3】:

      这是因为在您的合并函数中,lista 和 listb 变为 None 并传递给函数 您的 merge_sort 函数也不正确。 您可以使用以下代码来处理您的错误:

      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)
      

      【讨论】:

      • if not lista or not listb 语句到底是做什么的?您的版本正在运行,但它在 2 个元素的多个排序列表中返回它。
      • 这就是我告诉你的,我只是告诉你如何处理这些错误,合并列​​表功能需要修改,not lista or not listb 检查是否有任何一个是 None 如果是,它返回
      • 如果您觉得有用,可以接受答案
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-09-05
      • 2015-09-10
      • 2022-10-15
      • 1970-01-01
      • 2016-03-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多