[Python-ideas] Fwd: quantifications, and tuple patterns

Steven D'Aprano steve at pearwood.info
Sun Jan 15 03:01:24 CET 2012


Guido van Rossum wrote:
> On Sat, Jan 14, 2012 at 1:38 PM, Paul Moore <p.f.moore at gmail.com> wrote:
[...]
>> So, going back to what Annie was referring to, there seem to be three
>> key concepts:
>>
>> Quantifications, which are covered in Python by any() and all()
>> Capturing a "witness", which can be done using assignment-as-expression
>> Tuple matching, which you have shown can be handled using tuple
>> unpacking plus the generator expression if clause, but could probably
>> gain from a more compact notation.
>>
> 
> I'm not sure we need a new construct for tuple matching. Witness capturing
> seems the most important missing feature here.


If I recall correctly, there have been occasional discussions about changing 
any() and all() to return the item found rather than a flag. Given the need 
for backwards compatibility, I don't think we can or should do this, but a 
hypothetical quant module, or a few new built-ins, could possibly help here. 
I'm not sure that quantifications are quite important enough to justify new 
syntax.

For lack of better names:


def all2(iterable, pred=bool):
     """Like all(pred(obj) for obj in iterable), returning True if it is true,
     otherwise obj, the first witness that it false.
     """
     for obj in iterable:
         if not pred(obj):
             return obj
     return True

def any2(iterable, pred=bool):
     """Like any(pred(x) for x in iterable), returning False if it is false,
     otherwise obj, the first witness that it is true.
     """
     for obj in iterable:
         if pred(obj):
             return obj
     # I look forward to the bike-shedding about returning None
     # vs returning False ;)
     return False


One disadvantage of returning a single value to represent both the success or 
failure of the quantification *and* the witness is that it leaves the caller 
vulnerable to this sort of bug:

py> witness = any2([3, 0, 2, 4], lambda n: n%2==0)  # get first even number
py> if witness:
...     print("first even number is,", witness)
... else:
...     print("everything is odd")
...
everything is odd


I don't have a good solution for this.


-- 
Steven



More information about the Python-ideas mailing list