Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 用于空列表的安全max()函数_Python_List_Exception_Error Handling_Max - Fatal编程技术网

Python 用于空列表的安全max()函数

Python 用于空列表的安全max()函数,python,list,exception,error-handling,max,Python,List,Exception,Error Handling,Max,评估 max_val = max(a) 将导致错误 ValueError: max() arg is an empty sequence 除了使用try,捕获之外,是否还有更好的方法防止此错误 a = [] try: max_val = max(a) except ValueError: max_val = default 在Python 3.4+中,您可以使用: 在较低版本中,您可以使用或: >>> max([] or [99]) 99 注:第二种方

评估

max_val = max(a)
将导致错误

ValueError: max() arg is an empty sequence
除了使用
try
捕获之外,是否还有更好的方法防止此错误

a = []
try:
    max_val = max(a)
except ValueError:
    max_val = default 

在Python 3.4+中,您可以使用:

在较低版本中,您可以使用

>>> max([] or [99])
99
注:第二种方法并不适用于所有iterables。特别是对于迭代器,它只产生被考虑的真值

>>> max(iter([]) or 0)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: max() arg is an empty sequence
>最大值(iter([])或0)
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
ValueError:max()arg是一个空序列

一个空序列的最大值“应该”是一个无限小的东西,不管序列中的元素有什么类型。不幸的是,(1)对于空序列,您无法判断元素的类型;(2)例如,Python中没有最负整数

因此,如果您希望它在这种情况下做一些合理的事情,您需要帮助max。在Python的最新版本中,
max
有一个
default
参数(在我看来这是一个误导性的名称,但没关系),如果以空序列传递,将使用该参数。在旧版本中,您只需确保传入的序列不是空的——例如,通过
将其与包含您希望在这种情况下使用的值的单例序列相匹配


[发布后很久才编辑,因为Yaakov Belch好心地在评论中指出,我写的是“无限大”,我应该写的是“无限小”。

在早于3.4的Python版本中,您可以使用
itertools.chain()
为可能为空的序列添加另一个值。这将处理任何空iterable,但请注意,它与提供
默认值
参数并不完全相同,因为额外的值始终包含在内:

>>> from itertools import chain
>>> max(chain([42], []))
42
但在Python 3.4中,如果序列不是空的,则忽略默认值:

>>> max([3], default=42)
3

考虑到上面的所有注释,它可以是这样的包装器:

def max_safe(*args, **kwargs):
    """
    Returns max element of an iterable.

    Adds a `default` keyword for any version of python that do not support it
    """
    if sys.version_info < (3, 4):  # `default` supported since 3.4
        if len(args) == 1:
            arg = args[0]
            if 'default' in kwargs:
                default = kwargs.pop('default')
                if not arg:
                    return default

                # https://stackoverflow.com/questions/36157995#comment59954203_36158079
                arg = list(arg)
                if not arg:
                    return default

                # if the `arg` was an iterator, it's exhausted already
                # so use a new list instead
                return max(arg, **kwargs)

    return max(*args, **kwargs)
def max_safe(*args,**kwargs):
"""
返回iterable的最大元素。
为不支持它的任何python版本添加“default”关键字
"""
如果sys.version_info<(3,4):#从3.4开始支持默认值
如果len(args)==1:
arg=args[0]
如果kwargs中为“默认值”:
default=kwargs.pop('default')
如果不是arg:
返回默认值
# https://stackoverflow.com/questions/36157995#comment59954203_36158079
arg=列表(arg)
如果不是arg:
返回默认值
#如果'arg'是迭代器,那么它已经用完了
#因此,请使用一个新列表
返回最大值(arg,**kwargs)
返回最大值(*args,**kwargs)

另一种解决方案是使用三元运算符:

nums = []
max_val = max(nums) if nums else 0

奖金:

def min_default(*args, **kwargs):
    """
    Adds support for "default" keyword argument when iterable is empty.
    Works for any iterable, any default value, and any Python version (versions >= 3.4
    support "default" parameter natively).

    Default keyword used only when iterable is empty:

    >>> min_default([], default=42)
    42

    >>> min_default([3], default=42)
    3

    All original functionality is preserved:

    >>> min_default([])
    Traceback (most recent call last):
    ValueError: min() arg is an empty sequence

    >>> min_default(3, 42)
    3
    """

    default = kwargs.pop('default', _DEFAULT)
    try:
        return min(*args, **kwargs)
    except ValueError:
        if default is _DEFAULT:
            raise
        return default

可以创建简单的lambda来执行此操作:

get_max = lambda val_list: max([ val for val in val_list if val is not None ]) if val_list else None
您可以这样称呼它:

get\u max(你的列表)

@vaultah为什么你没有发布答案作为答案@吸烟者:因为它太简单了。@ah。。。发布“太简单”的答案有什么不对?现在,其他人必须……3.4之前版本的另一个选择是创建一个模仿新行为的
my_max
函数。
max(iter([])或0)
正是让我感到悲伤的原因。。。你对如何处理它还有什么进一步的建议吗?其次,我从来没有想过要检查文件。。。我认为这样一个简单的函数是一对一的process@AlexanderMcFarlane,邓肯提出了一个不错的选择。看看吧。@Alexander McFarlane,我不是以英语为母语的人。我不明白什么是一对一输出过程。这是否意味着一个普通的任务?@falsetru by one-in-one-out我指的是一个参数输入和一个返回值:)这是违反直觉的:一个空列表的最大值应该是无限小的(因此max(x,list…=max(x,max(list…)),而一个空列表的最小值应该是无限大的;我道歉。我会修正我的答案,相信你发现了错误。[…完成。再次感谢。]是否有任何理由在简单列表连接上使用
,例如
max([42],])
,其中默认值为
42
?@MajorInc使用多个参数调用
max
,与使用单个参数调用具有不同的含义。对于单个iterable参数,
max
将返回它包含的最大元素,但是对于多个参数,它将直接比较它们(即,它不会迭代)。e、 g.
max([42],])
是一个列表
[42]
但是
max(chain([42],])
max([],default=42)
都给出
42
最大安全(42,3,default=0)
抛出
TypeError:max()得到一个意外的关键字参数
(python 2)
_DEFAULT = object()

def max_default(*args, **kwargs):
    """
    Adds support for "default" keyword argument when iterable is empty.
    Works for any iterable, any default value, and any Python version (versions >= 3.4
    support "default" parameter natively).

    Default keyword used only when iterable is empty:

    >>> max_default([], default=42)
    42

    >>> max_default([3], default=42)
    3

    All original functionality is preserved:

    >>> max_default([])
    Traceback (most recent call last):
    ValueError: max() arg is an empty sequence

    >>> max_default(3, 42)
    42
    """

    default = kwargs.pop('default', _DEFAULT)
    try:
        return max(*args, **kwargs)
    except ValueError:
        if default is _DEFAULT:
            raise
        return default
def min_default(*args, **kwargs):
    """
    Adds support for "default" keyword argument when iterable is empty.
    Works for any iterable, any default value, and any Python version (versions >= 3.4
    support "default" parameter natively).

    Default keyword used only when iterable is empty:

    >>> min_default([], default=42)
    42

    >>> min_default([3], default=42)
    3

    All original functionality is preserved:

    >>> min_default([])
    Traceback (most recent call last):
    ValueError: min() arg is an empty sequence

    >>> min_default(3, 42)
    3
    """

    default = kwargs.pop('default', _DEFAULT)
    try:
        return min(*args, **kwargs)
    except ValueError:
        if default is _DEFAULT:
            raise
        return default
get_max = lambda val_list: max([ val for val in val_list if val is not None ]) if val_list else None