【问题标题】:Python: min(None, x)Python:分钟(无,x)
【发布时间】:2011-09-09 10:30:50
【问题描述】:

我想执行以下操作:

a=max(a,3)
b=min(b,3)

但有时ab 可能是None
我很高兴地发现在max 的情况下效果很好,给出了我需要的结果3,但是如果bNoneb 仍然是None...

任何人都可以想到一个优雅的小技巧,让min 返回数字,以防万一没有参数之一?

【问题讨论】:

  • 它没有做正确的事情。它恰好在两种情况之一中给出了您期望的结果,因为NoneTypeint 之间的无意义比较返回一个固定值,而不管整数值如何。在 Python 3 中,当您执行类似操作(比较没有有意义的排序的类型)时,您会得到一个 TypeError
  • 似乎是 Python 中的一个不一致之处,最重要的是。
  • 如果您可以将 None 替换为默认的 int 值(如 0),您可以执行以下操作:max(a,3,key=lambda x: x or 0)

标签: python python-2.x


【解决方案1】:

为什么不创建一个没有 None 值的生成器?它更简单、更干净。

>>> l=[None ,3]
>>> min(i for i in l if i is not None)
3

【讨论】:

  • 不需要列表理解。仍然 +1(提前 - 认真,请删除括号),这是一个干净简单的解决方案。
  • 谢谢,没有大括号,Python 会像生成器表达式一样解释它吗?
  • 是的。如果genexpr 是函数调用的唯一参数,则生成器表达式周围的括号是可选的。
  • 这样的解决方案的一个潜在问题是它适用于列出的示例,但如果您有一个带有[None, None] 的列表,min() 函数将失败,因为您没有给出它一个有效的论点。
  • @KevinLondon,根据您想要的行为将 min 的默认值指定为 0 或 None。 min((x for x in [None,None] if x is not None), default=None)
【解决方案2】:

我对 Python 3(3.4 及更高版本)的解决方案:

min((x for x in lst if x is not None), default=None)
max((x for x in lst if x is not None), default=None)

【讨论】:

    【解决方案3】:

    Python 3 的解决方案

    代码

    #变量 lst 是你的序列

    min(filter(lambda x: x is not None, lst)) if any(lst) else None
    

    示例:

    In [3]: lst = [None, 1, None]
    
    In [4]: min(filter(lambda x: x is not None, lst)) if any(lst) else None
    Out[4]: 1
    
    In [5]: lst = [-4, None, 11]
    
    In [6]: min(filter(lambda x: x is not None, lst)) if any(lst) else None
    Out[6]: -4
    
    In [7]: lst = [0, 7, -79]
    
    In [8]: min(filter(lambda x: x is not None, lst)) if any(lst) else None
    Out[8]: -79
    
    In [9]: lst = [None, None, None]
    
    In [10]: min(filter(lambda x: x is not None, lst)) if any(lst) else None
    
    In [11]: print(min(filter(lambda x: x is not None, lst)) if any(lst) else None)
    None
    

    注意事项:

    按顺序呈现为数字和无。如果所有值都是 None min() 引发异常

    ValueError: min() arg 是一个空序列

    这段代码完全解决了这个问题

    优点:

    1. 如果没有按顺序出现,则工作
    2. 使用 Python 3
    3. max() 也可以使用

    缺点

    1. 列表中需要多个非零变量。即 [0,None] 失败。
    2. 需要一个变量(例如lst)或需要复制序列

    【讨论】:

    • 这也适用于 Python 2.7。由于它还解决了其他解决方案的 min(None) 问题,它得到了我的 +1
    • 一个不能处理的边界情况是lst 可能只包含 0 和 None 值。您希望它返回 0,但它会返回 None。
    • 很好的答案和例子!
    【解决方案4】:

    这是一个内联装饰器,您可以使用它来过滤掉可能传递给函数的 None 值:

    noNones = lambda fn : lambda *args : fn(a for a in args if a is not None)
    print noNones(min)(None, 3)
    print noNones(max)(None, 3)
    

    打印:

    3
    3
    

    【讨论】:

      【解决方案5】:
      def max_none(a, b):
          if a is None:
              a = float('-inf')
          if b is None:
              b = float('-inf')
          return max(a, b)
      
      def min_none(a, b):
          if a is None:
              a = float('inf')
          if b is None:
              b = float('inf')
          return min(a, b)
      
      max_none(None, 3)
      max_none(3, None)
      min_none(None, 3)
      min_none(3, None)
      

      【讨论】:

      • 请注意,这仅在默认值为 0 时有效。传递 0 而不是 None 仍会触发传递默认值,但不会更改值,因为默认值为 0(和 0 == 0.0 == 0j)。
      • OP 说 max 不是问题。如果 b 为负数会怎样?
      【解决方案6】:

      您可以使用内联 if 和 infinity 作为默认值,因为这适用于任何值:

      a = max(a if a is not None else float('-inf'), 3)
      b = min(b if b is not None else float('inf'), 3)
      

      【讨论】:

      • 好的,那我就说得更清楚一点
      • 那么这有时会通过True ;)
      【解决方案7】:
      a=max(a,3) if a is not None else 3
      b=min(b,3) if b is not None else 3
      

      【讨论】:

      • 我总是尽量避免否定。所以我更喜欢b = 3 if b is None else min(b, 3)
      【解决方案8】:

      @utdemir 的回答非常适合提供的示例,但在某些情况下会引发错误。

      出现的一个问题是,如果您的列表仅包含 None 值。如果您向min() 提供一个空序列,则会引发错误:

      >>> mylist = [None, None]
      >>> min(value for value in mylist if value)
      Traceback (most recent call last):
        File "<stdin>", line 1, in <module>
      ValueError: min() arg is an empty sequence
      

      因此,这个 sn-p 可以防止错误:

      def find_minimum(minimums):
          potential_mins = (value for value in minimums if value is not None)
          if potential_mins:
              return min(potential_mins)
      

      【讨论】:

        【解决方案9】:

        我相信最干净的方法是使用过滤器内置功能

        a = max(filter(None, [a, 3]))
        b = min(filter(None, [b, 3]))
        

        【讨论】:

        • 这会过滤掉零。
        猜你喜欢
        • 1970-01-01
        • 2023-03-31
        • 1970-01-01
        • 1970-01-01
        • 2022-08-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-04-26
        相关资源
        最近更新 更多