評価する、
max_val = max(a)
エラーが発生します
ValueError: max() arg is an empty sequence
try
、except
キャッチ以外に、このエラーから保護するより良い方法はありますか?
a = []
try:
max_val = max(a)
except ValueError:
max_val = default
Python 3.4+では、 default
キーワード引数 :を使用できます。
>>> max([], default=99)
99
下位バージョンでは、or
を使用できます:
>>> max([] or [99])
99
注:2番目のアプローチは、すべての反復可能オブジェクトに対して機能するわけではありません。特に、真理値のみを考慮したイテレータに対して。
>>> max(iter([]) or 0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: max() arg is an empty sequence
Python 3.4より古いバージョンでは、itertools.chain()
を使用して、空のシーケンスに別の値を追加できます。これにより、空の反復可能オブジェクトが処理されますが、余分な値が常に含まれているため、default
引数を指定するのと同じです。
>>> from itertools import chain
>>> max(chain([42], []))
42
ただし、Python 3.4では、シーケンスが空でない場合、デフォルトは無視されます。
>>> max([3], default=42)
3
別の解決策は、三項演算子を使用することです。
nums = []
max_val = max(nums) if nums else 0
または
max val = max(iter(nums) if nums else [0])
上記のすべてのコメントを考慮すると、次のようなラッパーになります。
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)
空のシーケンスの最大値は、シーケンスの要素が持つあらゆるタイプの無限に小さなものでなければなりません。残念なことに、(1)空のシーケンスでは、要素がどのタイプを持っているのかわからず、(2)Pythonで最も負の整数のようなものはありません。
したがって、この場合に賢明なことをしたい場合は、max
outを支援する必要があります。 Pythonの最近のバージョンでは、default
にmax
引数があります(これは誤解を招く名前のように見えますが、気にしません)。空のシーケンスを渡します。古いバージョンでは、渡すシーケンスが空でないことを確認する必要があります。たとえば、使用したい値を含むシングルトンシーケンスでor
ingすることによってその場合。
[Yaakov Belchが「無限に大きい」と書いたコメントで親切に指摘していたので、投稿してからずっと編集しました。