Provide a 'key' argument for all() and any() builtins
This would be similar to 'key' argument already available for min(), max() and sorted() and would let user decide what must be considered True and what not. Some use cases: all(a, b, c, ... key=callable) all(a, b, c, ... key=lambda x: isinstance(x, int)) any(a, b, c, ... key=lambda x: x < 10) a = b = c = None for x in foo: if cond1: a = 0 elif cond2: b = 0 elif cond3: c = 0 # meaning all cond* has been satisfied and it's ok to consider 0 a meaningful value assert all(a, b, c, key=lambda x: x != None) Thoughts? --- Giampaolo http://code.google.com/p/pyftpdlib/ http://code.google.com/p/psutil/ http://code.google.com/p/pysendfile/
On Jul 22, 2012, at 11:03 PM, Giampaolo Rodolà wrote:
This would be similar to 'key' argument already available for min(), max() and sorted() and would let user decide what must be considered True and what not.
There's no need. We already have: >>> all(predicate(x) for x in iterable) >>> any(predicate(x) for x in iterable) Raymond
On Sun, Jul 22, 2012 at 9:36 PM, Raymond Hettinger <raymond.hettinger@gmail.com> wrote:
On Jul 22, 2012, at 11:03 PM, Giampaolo Rodolà wrote:
This would be similar to 'key' argument already available for min(), max() and sorted() and would let user decide what must be considered True and what not.
There's no need. We already have:
>>> all(predicate(x) for x in iterable) >>> any(predicate(x) for x in iterable)
In addition, there's a reason why the key= parameter to sort, sorted, max and min can't be replaced with a similar idiom: all these return the *original* object(s) and the key= parameter affects only the comparison; for example, try max(1,-2,3,-4, key=abs). Whereas for the current proposal, the value returned by the key would also determine the outcome -- and then there is no advantage over using the comprehension. More general, if you can first apply the transformation (the key function) and then the aggregation function (min/max/etc.), there's no need to combine the transformation and the aggregation. But in all the cases that have a key= parameter, this is not so. -- --Guido van Rossum (python.org/~guido)
On 23 July 2012 15:55, Guido van Rossum <guido@python.org> wrote:
On Sun, Jul 22, 2012 at 9:36 PM, Raymond Hettinger <raymond.hettinger@gmail.com> wrote:
On Jul 22, 2012, at 11:03 PM, Giampaolo Rodolà wrote:
This would be similar to 'key' argument already available for min(), max() and sorted() and would let user decide what must be considered True and what not.
There's no need. We already have:
>>> all(predicate(x) for x in iterable) >>> any(predicate(x) for x in iterable)
In addition, there's a reason why the key= parameter to sort, sorted, max and min can't be replaced with a similar idiom: all these return the *original* object(s) and the key= parameter affects only the comparison; for example, try max(1,-2,3,-4, key=abs).
Whereas for the current proposal, the value returned by the key would also determine the outcome -- and then there is no advantage over using the comprehension. More general, if you can first apply the transformation (the key function) and then the aggregation function (min/max/etc.), there's no need to combine the transformation and the aggregation. But in all the cases that have a key= parameter, this is not so.
To put it yet another way, the key= parameter encapsulates the decorate-process-undecorate pattern, and that pattern doesn't apply to any/all. Paul.
On Sun, Jul 22, 2012 at 9:03 PM, Giampaolo Rodolà <g.rodola@gmail.com> wrote:
This would be similar to 'key' argument already available for min(), max() and sorted() and would let user decide what must be considered True and what not. Some use cases:
all(a, b, c, ... key=callable)
You're missing some brackets or parens there: all([a, b, c, ...], key=callable) <snip>
Thoughts?
I see negligible advantage over just writing the generator expression directly: all(callable(item) for item in iterable) === all(iterable, key=callable) (which is about comparable to the difference between a map() invocation vs. a list comprehension, and the choice there seems to be largely a matter of taste) min() & max() return the result object satisfying the constraint, so the `key` argument makes sense for when you want to e.g. find the cheapest house rather than the price of the cheapest house. In contrast, any() & all() *always* just return a simple bool result, not the object whose truthiness determined the predicate's result, so `key` would be pointless since the result gets converted to a plain bool anyway (or at least, we can conceptualize the implementation as if it worked that way). Cheers, Chris
2012/7/23 Chris Rebert <pyideas@rebertia.com>
On Sun, Jul 22, 2012 at 9:03 PM, Giampaolo Rodolà <g.rodola@gmail.com> wrote:
This would be similar to 'key' argument already available for min(), max() and sorted() and would let user decide what must be considered True and what not. Some use cases:
all(a, b, c, ... key=callable)
You're missing some brackets or parens there: all([a, b, c, ...], key=callable)
<snip>
Thoughts?
I see negligible advantage over just writing the generator expression directly: all(callable(item) for item in iterable)
<snip>
min() & max() return the result object satisfying the constraint, so the `key` argument makes sense for when you want to e.g. find the cheapest house rather than the price of the cheapest house. In contrast, any() & all() *always* just return a simple bool result, not the object whose truthiness determined the predicate's result, so `key` would be pointless since the result gets converted to a plain bool anyway (or at least, we can conceptualize the implementation as if it worked that way).
Agreed. Please ignore my proposal then. --- Giampaolo https://code.google.com/p/pyftpdlib/ https://code.google.com/p/psutil/ https://code.google.com/p/pysendfile/
participants (5)
-
Chris Rebert
-
Giampaolo Rodolà
-
Guido van Rossum
-
Paul Moore
-
Raymond Hettinger