【问题标题】:Python unorderable types: NoneType() > int() when finding max of a listPython 不可排序的类型:NoneType() > int() 查找列表的最大值时
【发布时间】:2017-03-04 09:58:45
【问题描述】:

几天前我刚开始使用python 3。在编程时,我遇到了奇怪的情况

a = [
     [5, [[1, 1, None], [None, None, None], [None, None, None]]], 
     [5, [[1, None, 1], [None, None, None], [None, None, None]]]
    ]

max(a)给我

Traceback(最近一次调用最后一次):文件“”,第 1 行,in TypeError:不可排序的类型:NoneType() > int()

但如果我尝试

a = [
     [5, [[1, 1, None], [None, None, None], [None, None, None]]], 
     [5.1, [[1, None, 1], [None, None, None], [None, None, None]]]
    ]

max(a) 显示

[5.1, [[1, None, 1], [None, None, None], [None, None, None]]]

这种行为有什么特殊原因吗?

更新 1: 我尝试了一些不同的东西

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

max(a)[5, [[5, 6], [7, 8]]] 我的疑问是为什么在这种情况下没有显示错误?

【问题讨论】:

  • 您对哪个部分感到困惑?如果列表的第一个元素不相等,则无需与第二个元素绑定。
  • 投反对票有什么特别的原因吗?
  • @jonrsharpe:好吧..我怀疑为什么 python 向我显示错误?对于[[5, [[1,2], [3,4]]],[5,[[3,4],[5,6]]],[5,[[5,6],[7,8]]]] ,输出为[5, [[5, 6], [7, 8]]],为什么没有显示相同的错误?
  • 为什么你认为你会得到同样的错误?该示例包含哪些不可排序的类型?
  • 您不能将不可排序的类型混合在一起并期望max 会起作用。

标签: python python-3.x


【解决方案1】:

这是因为max 在遇到 None 值时会这样做:

max([1, None])

同样报错:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-14-c33cf47436bc> in <module>()
----> 1 max([1,None])

TypeError: unorderable types: NoneType() > int()

基本上 max 是尝试遍历列表并首先找出较大的值。但当它达到 None 时,它​​无法再进行比较,因此会引发错误。

a = [
     [5, [[1, 1, None], [None, None, None], [None, None, None]]], 
     [5.1, [[1, None, 1], [None, None, None], [None, None, None]]]
    ]

它比较 5 和 5.1 并认为 5.1 的列表更大。

当两个第一个值都是 5 时,它会迭代下一个项目并遇到导致错误的 None

更新:

此示例可能有助于更好地阐明错误消息:

max([1,'2'])

错误:

TypeError: unorderable types: str() > int()

基本上它试图比较'2' with 1并给出TypeError: unorderable types: str() &gt; int()

之前我们比较了None with int() 1,我们得到的错误信息是TypeError: unorderable types: NoneType() &gt; int()

【讨论】:

    【解决方案2】:

    在 Python 2 中,这个None 技巧在某些情况下非常有用,当您需要一个无法预测的最小值时(因为整数没有像 C 中那样固定的最小值/最大值)。

    在 Python 3 中,这不再是可能的了(而且大多数时候它是最好的,在将字符串与整数(例如 "2" 和 3)进行比较时,它可以省去很多麻烦。

    如果你真的需要,我想了一个解决方法。

    您可以定义一个低于任何其他对象的类并使用该类的实例而不是None

    class AM:
        def __int__(self):
            return 0
        def __gt__(self,other):
            return False
        def __repr__(self):
            return "INF"   # prints out nicely
    
    always_min = AM()
    
    a = [
         [5, [[1, 1, always_min], [always_min, always_min, always_min]]],
         [5, [[1, always_min, 1], [always_min, always_min, always_min]]]
        ]
    
    print(max(a))
    

    我明白了:

    [5, [[1, 1, INF], [INF, INF, INF]]]
    

    这证明了 tiebreak 有效。

    请注意,这是一个最小的实现。 max 仅使用 >: 仅定义 __gt__ 是惰性的,我们需要相应地定义其他 __ge____le____lt__ 以用于一般用法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-23
      • 2018-06-05
      • 2014-08-14
      相关资源
      最近更新 更多