Any, All predicates (and vector operations for free)

Christos TZOTZIOY Georgiou DLNXPEGFQVEB at spammotel.com
Tue Feb 18 09:56:06 EST 2003


On Mon, 17 Feb 2003 18:24:54 -0700, rumours say that Steven Taschuk
<staschuk at telusplanet.net> might have written:

>Quoth Christos TZOTZIOY Georgiou:
>> I have created a class that allows ANY and ALL predicates on iterables;
>> it was easy to also allow vector operations (eg add something to every
>> item on the list).
...
>But I'm not sure I understand how these predicates can be
>composed.  Suppose I have a list of lists of integers, and wish to
>verify that each list of integers contains something greater than
>2.  That is, I wish to check that
>	(all x in L)(exists y in x)(y > 2)
>So, I write
>	Any(All(L)) > 2
>Right?

No, unfortunately not.  The only way I did this was with a list
comprehension for the inner lists:

>>> from predicates import All
>>> l1=[ [1,2,3], [2,3,4], [5,6,7] ]
>>> l2=[ [1,2,3], [2,11,3], [6,4,2] ]
>>> bool(All([All(x)<10 for x in l1]))
True
>>> bool(All([All(x)<10 for x in l2]))
False

If lists had a max method (now there is only a builtin max function),
you would be able to say:

if All(L).max > 2: # ...

But in this specific example (I checked for > 10 instead of > 2), this
might be preferred:
>>> len([x for x in L if max(x)>10])==len(L)

There is a better (faster) version of this module in
<URL:http://www.sil-tec.gr/~tzot/python/predicates.py>, for which I
created a link in the Vaults yesterday, but it hasn't shown up yet.  The
new version uses generators and the new itertools module, so it applies
only for post-2.3a1 Pythons (ie current CVS).

In another message which I thought I posted but quite probably sent only
through email to Alex (I must have pressed 'r' (eply) instead of 'f'
(ollow-up)), I said about including some benchmark time 

>I was not able to get this to work with the code as written
>(though admittedly I did not spend much time on it), and am not
>sure it could ever work sensibly.  For example, what should
>All(L).__iter__ return?  An iterator over the elements of L?  An
>iterator of L's elements' iterators?  A "flattened" iterator over
>those elements' elements?

The current All(...) is an iterator itself, so All(...).__iter__ returns
self (ie none of the above).

>I think I'd prefer a scheme under which I'd write
>	all(L, lambda x: exists(x, lambda y: y > 2))
>which is more verbose, but (to me at least) easier to parse.  Also
>the implementation is trivial, short-circuiting is easy, and no
>difficult semantic questions arise.  (It's really just a
>generalization of map, etc., to generic iterables.)

Yes, although I think the syntax my module allows is much more pleasant
to the (my :) eye.

Thanks for your time!
-- 
TZOTZIOY, I speak England very best,
Real email address: 'dHpvdEBzaWwtdGVjLmdy\n'.decode('base64')




More information about the Python-list mailing list