Auswerten,
max_val = max(a)
wird den Fehler verursachen,
ValueError: max() arg is an empty sequence
Gibt es einen besseren Schutz gegen diesen Fehler als eine try
, except
catch?
a = []
try:
max_val = max(a)
except ValueError:
max_val = default
In Python 3.4 und höher können Sie das default
-Schlüsselwortargument verwenden:
>>> max([], default=99)
99
In der niedrigeren Version können Sie or
verwenden:
>>> max([] or [99])
99
HINWEIS: Der zweite Ansatz funktioniert nicht für alle Iterables. vor allem für Iteratoren, die nichts anderes ergeben als den betrachteten Wahrheitswert.
>>> max(iter([]) or 0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: max() arg is an empty sequence
In älteren Python-Versionen als 3.4 können Sie itertools.chain()
verwenden, um der möglicherweise leeren Sequenz einen weiteren Wert hinzuzufügen. Dies behandelt alle leeren Iterationen. Beachten Sie jedoch, dass es nicht genau dasselbe ist, als das Argument default
anzugeben, da der zusätzliche Wert immer enthalten ist:
>>> from itertools import chain
>>> max(chain([42], []))
42
In Python 3.4 wird der Standardwert jedoch ignoriert, wenn die Sequenz nicht leer ist:
>>> max([3], default=42)
3
Eine andere Lösung könnte die Verwendung von ternären Operatoren sein:
nums = []
max_val = max(nums) if nums else 0
oder
max val = max(iter(nums) if nums else [0])
In Anbetracht aller obigen Kommentare kann es sich um einen Wrapper handeln:
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)
Das Maximum einer leeren Sequenz "sollte" eine unendlich kleine Sache sein, unabhängig von der Art der Elemente der Sequenz. Unglücklicherweise können Sie (1) mit einer leeren Sequenz nicht sagen, welchen Typ die Elemente haben sollen, und (2) gibt es beispielsweise keine negativste Ganzzahl in Python.
Sie müssen also max
helfen, wenn Sie in diesem Fall etwas sinnvolles tun möchten. In den letzten Versionen von Python gibt es ein default
-Argument für max
(das scheint mir ein irreführender Name zu sein, aber egal), das verwendet wird, wenn Sie eine leere Sequenz übergeben. In älteren Versionen müssen Sie lediglich sicherstellen, dass die übergebene Sequenz nicht leer ist - beispielsweise durch or
ing mit einer Singleton-Sequenz, die den Wert enthält, den Sie in diesem Fall verwenden möchten.
[Lange nach dem Posting herausgegeben, weil Yaakov Belch in Kommentaren freundlich darauf hingewiesen hatte, dass ich "unendlich groß" geschrieben habe, wo ich "unendlich klein" hätte schreiben sollen.]