"any" and "all" support multiple arguments

Hi all, In "min" and "max" builtin-func, it support two style of args: min(...) min(iterable, *[, default=obj, key=func]) -> value min(arg1, arg2, *args, *[, key=func]) -> value But for "any" and "all", it only support iterable: all(iterable, /) Return True if bool(x) is True for all values x in the iterable. I'm not sure if this is discuss before, but can "any" and "all" support like min_max "arg1, arg2, *args" style? Thanks, Louie.

On 1 August 2017 at 14:01, Louie Lu <me@louie.lu> wrote:
I'm not sure if this is discuss before, but can "any" and "all" support like min_max "arg1, arg2, *args" style?
I don't see any particular reason why not, but is there a specific use case for this or is it just a matter of consistency? Unlike max and min, we already have operators in this case (and/or). I'd imagine that if I had a use for any(a, b, c) I'd write it as a or b or c, and for all(a, b, c) I'd write a and b and c. Paul

On 1 August 2017 at 23:24, Paul Moore <p.f.moore@gmail.com> wrote:
On 1 August 2017 at 14:01, Louie Lu <me@louie.lu> wrote:
I'm not sure if this is discuss before, but can "any" and "all" support like min_max "arg1, arg2, *args" style?
I don't see any particular reason why not, but is there a specific use case for this or is it just a matter of consistency? Unlike max and min, we already have operators in this case (and/or). I'd imagine that if I had a use for any(a, b, c) I'd write it as a or b or c, and for all(a, b, c) I'd write a and b and c.
Right, the main correspondence here is with "sum()": folks can't write "sum(a, b, c)", but they can write "a + b + c". The various container constructors are also consistent in only taking an iterable, with multiple explicit items being expected to use the syntactic forms (e.g. [a, b, c], {a, b, c}, (a, b, c)) The same rationale holds for any() and all(): supporting multiple positional arguments would be redundant with the existing binary operator syntax, with no clear reason to ever prefer one option over the other. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

On 2017-08-01 17:28, Nick Coghlan wrote:
Right, the main correspondence here is with "sum()": folks can't write "sum(a, b, c)", but they can write "a + b + c".
The various container constructors are also consistent in only taking an iterable, with multiple explicit items being expected to use the syntactic forms (e.g. [a, b, c], {a, b, c}, (a, b, c))
The same rationale holds for any() and all(): supporting multiple positional arguments would be redundant with the existing binary operator syntax, with no clear reason to ever prefer one option over the other.
Isn't there a difference, though, insofar as we don't have a '+/sum' or 'and/all' equivalent of [a, b, *c]? You need to write 1 + 3 + sum(xs), or a and b and all(ys). Or, of course, any(chain([a], [b], c)), but that is not pretty. Clément.

On Tuesday, August 1, 2017 at 12:58:24 PM UTC-4, Clément Pit-Claudel wrote:
On 2017-08-01 17:28, Nick Coghlan wrote:
Right, the main correspondence here is with "sum()": folks can't write "sum(a, b, c)", but they can write "a + b + c".
The various container constructors are also consistent in only taking an iterable, with multiple explicit items being expected to use the syntactic forms (e.g. [a, b, c], {a, b, c}, (a, b, c))
The same rationale holds for any() and all(): supporting multiple positional arguments would be redundant with the existing binary operator syntax, with no clear reason to ever prefer one option over the other.
Isn't there a difference, though, insofar as we don't have a '+/sum' or 'and/all' equivalent of [a, b, *c]? You need to write 1 + 3 + sum(xs), or a and b and all(ys). Or, of course, any(chain([a], [b], c)), but that is not pretty.
a or b or any(c) seems clear to me.
Clément. _______________________________________________ Python-ideas mailing list Python...@python.org <javascript:> https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/

On 2 August 2017 at 02:57, Clément Pit-Claudel <cpitclaudel@gmail.com> wrote:
On 2017-08-01 17:28, Nick Coghlan wrote:
The same rationale holds for any() and all(): supporting multiple positional arguments would be redundant with the existing binary operator syntax, with no clear reason to ever prefer one option over the other.
Isn't there a difference, though, insofar as we don't have a '+/sum' or 'and/all' equivalent of [a, b, *c]? You need to write 1 + 3 + sum(xs), or a and b and all(ys). Or, of course, any(chain([a], [b], c)), but that is not pretty.
Function calls create an argument tuple anyway, so writing "any(a, b, *ys)" wouldn't actually be significantly more efficient than the current "any((a, b, *ys))" (note the doubled parentheses). You'd potentially save the allocation of a single element tuple to hold the full tuple, but single element tuples are pretty cheap in the grand scheme of things, and Python interpreter implementations often attempt to avoid creating one in the single-positional argument case (since they'd just need to unpack it again to stick it in the corresponding parameter slot). This means that in the case where what you actually want is lazy iteration over the trailing iterable, then you have to use the itertools.chain form: "any(chain((a, b), ys))" The chained binary operator forms also both seem clearer to me than either "sum(1, 3, *xs)" or "any(a, b, *ys)", as those formulations require that the reader know a Python-specific idiosyncratic concept and notation (iterable unpacking), while the binary operator based forms can be interpreted correctly based solely on knowledge of either arithmetic ("+", "sum") or logic ("and", "all"). So while this is an entirely reasonable design question to ask, it turns out there are a few good reasons not to actually make the change: - it doesn't add expressiveness to the language (the binary operator forms already exist, as does the double-parenthesis form) - it doesn't add readability to the language (the iterable unpacking form requires more assumed knowledge than the binary operator form) - it doesn't improve the efficiency of the language (iterable unpacking is an eager operation, not a lazy one, even in function calls) - min() and max() are actually the odd ones out here (for historical reasons), not any(), all() Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

I'd be more interested in supporting the "key" function: any(users, key=User.is_admin) As opposed to: any(user.is_admin() for user in users) 1.8.2017 16.07 "Louie Lu" <me@louie.lu> kirjoitti: Hi all, In "min" and "max" builtin-func, it support two style of args: min(...) min(iterable, *[, default=obj, key=func]) -> value min(arg1, arg2, *args, *[, key=func]) -> value But for "any" and "all", it only support iterable: all(iterable, /) Return True if bool(x) is True for all values x in the iterable. I'm not sure if this is discuss before, but can "any" and "all" support like min_max "arg1, arg2, *args" style? Thanks, Louie. _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/

I find it frustrating that they always return booleans. It would be more useful if any() returned the first true value it finds. This seems like a backward-compatible-enough change to me... :) --Ned. On 8/1/17 9:32 AM, Markus Meskanen wrote:
I'd be more interested in supporting the "key" function:
any(users, key=User.is_admin)
As opposed to:
any(user.is_admin() for user in users)
1.8.2017 16.07 "Louie Lu" <me@louie.lu <mailto:me@louie.lu>> kirjoitti:
Hi all,
In "min" and "max" builtin-func, it support two style of args:
min(...) min(iterable, *[, default=obj, key=func]) -> value min(arg1, arg2, *args, *[, key=func]) -> value
But for "any" and "all", it only support iterable:
all(iterable, /) Return True if bool(x) is True for all values x in the iterable.
I'm not sure if this is discuss before, but can "any" and "all" support like min_max "arg1, arg2, *args" style?
Thanks, Louie. _______________________________________________ Python-ideas mailing list Python-ideas@python.org <mailto:Python-ideas@python.org> https://mail.python.org/mailman/listinfo/python-ideas <https://mail.python.org/mailman/listinfo/python-ideas> Code of Conduct: http://python.org/psf/codeofconduct/ <http://python.org/psf/codeofconduct/>
_______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/

On 1 August 2017 at 23:43, Ned Batchelder <ned@nedbatchelder.com> wrote:
I find it frustrating that they always return booleans. It would be more useful if any() returned the first true value it finds. This seems like a backward-compatible-enough change to me... :)
While I'm not sure how to interpret that smiley, I figure it's worth making it explicit that this is decidedly *not* true given type-dependent serialisation protocols like JSON: >>> import json >>> class MyClass: ... def __bool__(self): ... return True ... >>> json.dumps(any([MyClass()])) 'true' >>> json.dumps(MyClass()) Traceback (most recent call last): ... TypeError: Object of type 'MyClass' is not JSON serializable The idea of elevating first_true from its current status as an itertools recipe to actually being an itertools module API has certainly come up before, though. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

On Tue, Aug 1, 2017 at 6:01 AM, Louie Lu <me@louie.lu> wrote:
[...] I'm not sure if this is discuss before, but can "any" and "all" support like min_max "arg1, arg2, *args" style?
Can this be done consistently? For example consider x=[[]]. Then all(x) where x is interpreted as an iterable should be False, but all(x) where x is interpreted as a single argument should be True. This inconsistency already exists for max:
max({1, 2}) 2 max({1, 2}, {1}) set([1, 2])
However, it doesn't seem like there's a good reason to add an inconsistency to the API for any/all. - Lucas

On 8/1/2017 9:01 AM, Louie Lu wrote:
Hi all,
In "min" and "max" builtin-func, it support two style of args:
min(...) min(iterable, *[, default=obj, key=func]) -> value min(arg1, arg2, *args, *[, key=func]) -> value
To me, two APIs is a nuisance. For one thing, default has to be keyword only and not just optional. Compare with sum:
sum((2,3,4),5) 14
min((2,3,4),5) # Py3 Traceback (most recent call last): File "<pyshell#7>", line 1, in <module> min((2,3,4),5) TypeError: '<' not supported between instances of 'int' and 'tuple'
min((2,3,4),5) # Py2 5 min(5, (2,3,4)) 5
I believe that a version of the second was in original Python (and at least in 1.3) whereas the first was added later, likely with the new iterator protocol (2.2). In any case, with *unpacking in displays, the second is no longer needed.
min(4,3, *[1,2]) 1 min((4,3, *[1,2])) 1
If I am correct, perhaps the doc for max and min in https://docs.python.org/3/library/functions.html#max should mention that the 2nd is derived from the original syntax, kept for back compatibility (rather than a new innovation, to be imitated). I would rather get rid of the exceptional case than emulate it.
But for "any" and "all", it only support iterable:
all(iterable, /) Return True if bool(x) is True for all values x in the iterable.
As Nick pointed out, this is standard now.
list((1,2,3)) [1, 2, 3] list(1,2,3) Traceback (most recent call last): File "<pyshell#4>", line 1, in <module> list(1,2,3) TypeError: list() takes at most 1 argument (3 given)
-- Terry Jan Reedy
participants (9)
-
Clément Pit-Claudel
-
Louie Lu
-
Lucas Wiman
-
Markus Meskanen
-
Ned Batchelder
-
Neil Girdhar
-
Nick Coghlan
-
Paul Moore
-
Terry Reedy