[Python-ideas] 'default' keyword argument for max(), min()

spir denis.spir at free.fr
Thu Apr 16 11:13:38 CEST 2009


Le Wed, 15 Apr 2009 20:39:26 -0700,
Jared Grubb <jared.grubb at gmail.com> s'exprima ainsi:

> On 15 Apr 2009, at 11:17, Raymond Hettinger wrote:
> > [Adam Atlas]
> >> I propose adding a "default" keyword argument to max() and min(),   
> >> which provides a value to return in the event that an empty  
> >> iterable  is passed.
> >
> > Could you write your proposal out in pure python so
> > we can see how it interacts with the key-keyword
> > argument and how it works when the number of
> > positional arguments is not one.
> 
> Here's one option... I'm going to cheat a little here and just wrap  
> the built-in min, but a quick/simple answer could be:
> 
> def min2(*vars, **kw):
>       try:
>           if 'key' in kw:
>                return min(*vars, key=kw['key'])
>           return min(*vars)
>       except Exception:
>           if 'default' in kw:
>               return kw['default']
>           raise

Is the purpose of this proposal really to return a default value in *any* case of exception?

> > Will min(default=0) still return a TypeError?
> > Will min(1, 2, default=0) return 0 or 1?
> > Will min([1,2], default=0) return 1?  # different from min([0,1,2])
> 
> # Your examples
> min2() -> TypeError
> min2(default=0) -> 0
> min2(1,2,default=0) -> 1
> min2([1,2], default=0) -> 1
> 
> # Iterator that yields things that are not comparable
> min2([1, set()]) -> TypeError
> min2([1, set()], default=7 ) -> 7   ***1***
> 
> # Iterator that raises an exception
> def foo():
>     yield 1
>     raise ValueError
> 
> min(foo()) -> ValueError
> min2(foo()) -> ValueError
> min2(foo(), default=None)  -> None  ***2***

In the case #2 above, maybe there is some utility to get a default.
I consider the case #1 as real programming error that should be properly warned with an exception.

> Jared

Intuitively, I thought the proposal was rather about a possibly empty iterable, result of previous unpredictable computations; then calling:
   min(iterable, default=whatever)

>>> min([])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: min() arg is an empty sequence
>>> def min2(*vars, **kw):
...     # case vars holds (only) an empty iterable and "default" is provided
...     if len(vars) == 1:
...         thing = vars[0]
...         try:
...             if len(thing) == 0 and 'default' in kw:
...                 return kw['default']
...         except TypeError:
...             pass
...     # else normal min() behaviour
...     if 'default' in kw:
...         del kw['default']
...     return min(*vars, **kw)
>>> min2([], default='X')
'X'
>>> min2(1,set(), default='X')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 13, in min2
TypeError: can only compare to a set
>>> min2((1,set()), default='X')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 13, in min2
TypeError: can only compare to a set
>>> min(1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable
>>> min2(1, default='X')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 13, in min2
TypeError: 'int' object is not iterable
>>> min((1))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable
>>> min2((1), default='X')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 13, in min2
TypeError: 'int' object is not iterable
>>> min([1])
1
>>> min2([1], default='X')
1

But, as said before, I have no clue about exceptions raised by a generator.

Denis
------
la vita e estrany



More information about the Python-ideas mailing list