[Python-ideas] "any" and "all" support multiple arguments
Nick Coghlan
ncoghlan at gmail.com
Wed Aug 2 11:06:22 EDT 2017
On 2 August 2017 at 02:57, Clément Pit-Claudel <cpitclaudel at 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 at gmail.com | Brisbane, Australia
More information about the Python-ideas
mailing list