'for every' and 'for any'

Hans Nowak wurmy at earthlink.net
Sun May 26 19:20:02 EDT 2002


Oren Tirosh wrote:
> 
> Here's an idea for a possible language enhancement.  I'd like to hear your
> comments about it.  It's inspired by list comprehensions and I think the
> examples are pretty self-explanatory:
> 
> if not isinstance(x, str) for any x in args:
>   raise TypeError, "arguments must be of type str"
> 
> valid = i>0 for every i in vector
> 
> if dict2.has_key(k) for any k in dict1:
>   ...
> 
> The words 'any' and 'every' can be non-reserved keywords (like the word 'as'
> in "import foo as bar").  They are valid only after the keyword 'for' when
> it's used in a non-statement context.

Interesting. I don't know enough about the language internals
to judge whether this is doable or not, or whether it's a good
idea or not. I do think that these constructs can be emulated
though, and we don't even need too much hackery.

Let's start with defining the 'any' and 'every' functions:

>>> every = lambda a, b: a and b
>>> any = lambda a, b: a or b

> if not isinstance(x, str) for any x in args:
>   raise TypeError, "arguments must be of type str"

# error condition met: not everything's a string
>>> reduce(any, [not isinstance(x, str) for x in [23, 33, "foo"]])
1

# no error condition:
>>> reduce(any, [not isinstance(x, str) for x in ["foo", "bar"]])
0

> valid = i>0 for every i in vector

# not everything's > 0:
>>> reduce(every, [i>0 for i in [0, 1, 2]])
0

# but here it is:
>>> reduce(every, [i>0 for i in [4, 5, 6]])
1

> if dict2.has_key(k) for any k in dict1:

>>> d1 = {1:2, 3:4, 5:6}
>>> d2 = {1:3, 6:6}
>>> d3 = {0:2, 9:3}
# yes, there are some mutual keys
>>> reduce(any, [d2.has_key(k) for k in d1.keys()])
1
# not here though
>>> reduce(any, [d2.has_key(k) for k in d3.keys()])
0

It can be done even simpler:

>>> def Any(lst):
	return reduce(lambda a, b: a or b, lst)

>>> def Every(lst):
	return reduce(lambda a, b: a and b, lst)

# every number > 0
>>> Every([i>0 for i in [4, 5, 6]])
1
# not here though:
>>> Every([i>0 for i in [0, -2, 4]])
0
# yes, there are any numbers > 0
>>> Any([i>0 for i in [-2, 0, 2]])
1

(Disclaimer: I haven't these constructs extensively,
but they seem to work.)

Cheers,

-- 
Hans (base64.decodestring('d3VybXlAZWFydGhsaW5rLm5ldA==')) 
# decode for email address ;-)
The Pythonic Quarter:: http://www.awaretek.com/nowak/



More information about the Python-list mailing list