[Tutor] check for nested sequences & flatten [and/or special
Thu, 14 Feb 2002 10:35:21 -0800 (PST)
On Thu, 14 Feb 2002, Remco Gerlich wrote:
> > Here's a function that checks to see if a certain condition is true
> > anywhere in the list:
> > ###
> > def any(condition_function, seq):
> > """Returns 1 if any element in our sequence 'seq'
> > responds favorably to our 'condition_function'."""
> > for element in seq:
> > if condition_function(element):
> > return 1
> > return 0
> > ###
> If we're addicted, surely then this should read
> any = lambda condition, seq: reduce(lambda a,b: a or b, map(condition, seq))
Noooooo! *grin* Ok, I'm chastised.
> (and why isn't the 'or' operator in the operator module?)
Ah! This is a tricky one: 'or' and 'and' behave in a particularly special
way. Let's say that we try defining our own version of 'and' as a
>>> def myand(a, b): return a and b
In many cases, it will appear to do the right thing... but what about
something like this?
>>> 0 and 1/0
>>> myand(0, 1/0)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
ZeroDivisionError: integer division or modulo by zero
What's particularly special about 'and' and 'or' is that they
automagically short-circuit --- when we do something like:
0 and y
Python doesn't even need to look at 'y', since it knows that it's just
useless to proceed. By the same short-circuiting logic:
1 or y
just doesn't even try to evaluate y, since it sees a true value.
The reason that 'myand(0, 1/0)' breaks is because, when we do function
calls, Python needs to know what all the argument values are, so 'myand'
doesn't have the ability to short-circuit. This is probably why they're
not in the operator module, because there's no mechanism available for
them to work as functions.
Hope that made some sort of sense!