why any( ) instead of firsttrue( ) ?

D

danieldelay

Hi,

I find very useful in python the ability to use a list or number x like
a boolean :

if x :
do something


So I don't understand why was introduced the any( ) function defined as :

def any(iterable):
for element in iterable:
if element:
return True
return False

instead of a function firsttrue( ) that could have been defined as :

def firsttrue(iterable):
for element in iterable:
if element:
return element
return None

This function "firsttrue( )" could probably be used anywhere "any( )" is
used, but with the ability to retrieve the first element where
bool(element) is True, which may be sometimes usefull.

I suppose that there is a reason for that, does anybody know it ?

Daniel
 
I

Ian Kelly

This function "firsttrue( )" could probably be used anywhere "any( )" is
used, but with the ability to retrieve the first element where bool(element)
is True, which may be sometimes usefull.

I suppose that there is a reason for that, does anybody know it ?

Because it was designed as a replacement for "reduce(lambda x, y: x or
y, iterable)". The problem arises when the iterable is empty. What
false value should be returned? If the iterable is a sequence of
bools, then None doesn't fit. If the iterable is a sequence of
non-bool objects, then False doesn't fit. In the case of reduce, the
problem is solved by explicitly specifying an initial value to be used
when the sequence is empty, but I guess GVR didn't feel that was
appropriate here.

Cheers,
Ian
 
D

danieldelay

Le 09/06/2010 00:24, Ian Kelly a écrit :
Because it was designed as a replacement for "reduce(lambda x, y: x or
y, iterable)". The problem arises when the iterable is empty. What
false value should be returned? If the iterable is a sequence of
bools, then None doesn't fit. If the iterable is a sequence of
non-bool objects, then False doesn't fit. In the case of reduce, the
problem is solved by explicitly specifying an initial value to be used
when the sequence is empty, but I guess GVR didn't feel that was
appropriate here.

Cheers,
Ian

Thanks for your reply, it helps me to understand this choice wether I do
not agree with it.

"False" sounds natural for a function called "any()" which makes a
boolean calculus

"None" sounds natural for a function called "firsttrue()" which tries to
retrieve an element.

As the two make sense, I would have chosen the "firsttrue()" which is
more powerfull...

Perhaps "any()" whas choosen to keep a beautiful symmetry with "all()",
that I can interprete only as a boolean calculus.

Does GVR prefers beauty to power ?

firsttrue(line.strip() for line in '\n\n \n CHEERS \n'.split('\n'))

Daniel.
 
M

MRAB

danieldelay said:
Le 09/06/2010 00:24, Ian Kelly a écrit :

Thanks for your reply, it helps me to understand this choice wether I do
not agree with it.

"False" sounds natural for a function called "any()" which makes a
boolean calculus

"None" sounds natural for a function called "firsttrue()" which tries to
retrieve an element.

As the two make sense, I would have chosen the "firsttrue()" which is
more powerfull...

Perhaps "any()" whas choosen to keep a beautiful symmetry with "all()",
that I can interprete only as a boolean calculus.

Does GVR prefers beauty to power ?

firsttrue(line.strip() for line in '\n\n \n CHEERS \n'.split('\n'))
Should 'firsttrue' return None? Surely, if none are true then it should
raise an exception.
 
T

Tim Chase

Should 'firsttrue' return None? Surely, if none are true then it should
raise an exception.

which can fairly elegantly be written with stock-Python as

# try:
result = itertools.ifilter(None,(
# some arbitrary generator goes here
line.strip()
for line in
'\n\n \n CHEERS \n'.split('\n')
)).next()
# except StopIteration:
# result = YOUR_DEFAULT_HERE

-tkc
 
C

Carl Banks

Le 09/06/2010 00:24, Ian Kelly a crit :



Thanks for your reply, it helps me to understand this choice wether I do
not agree with it.

"False" sounds natural for a function called "any()" which makes a
boolean calculus

"None" sounds natural for a function called "firsttrue()" which tries to
retrieve an element.

As the two make sense, I would have chosen the "firsttrue()" which is
more powerfull...

Perhaps "any()" whas choosen to keep a beautiful symmetry with "all()",
that I can interprete only as a boolean calculus.

Does GVR prefers beauty to power ?

firsttrue(line.strip() for line in '\n\n \n CHEERS  \n'.split('\n'))


Given Python's approach to boolean semantics I'm surprised they did it
that way too. Pretty much all other boolean logic in Python will
returns whatever value short circuits the operation. Based on that, I
say it'd be perfectly consistent for any() and all() to do the same.

One nitpick: if no values are true it should return the final value,
not None, because "any([a,b,c])" should be exactly equivalent to "a or
b or c".

My best guess why they did it that is for the interactive prompt (so
that it would print True or False). But then why didn't they do that
for "and" and "or"?

Having said that, the behavior of any() and all() is closer to the
boolean semantics I'd prefer. The current semantics tempt too many
programmers to use erroneous hacks like:

x and y or z

or merely readability-lacking hacks like:

x or y



Carl Banks
 
R

Raymond Hettinger

   def firsttrue(iterable):
     for element in iterable:
         if element:
             return element
     return None

This function "firsttrue( )" could probably be used anywhere "any( )" is
used, but with the ability to retrieve the first element where
bool(element) is True, which may be sometimes usefull.

FWIW, it's not hard to roll your own fast itertools variants of any()
and all():

next(ifilter(None, d), False) # first true, else False

next(ifilterfalse(None, d), True) # first false, else True

Raymond
 
D

danieldelay

Le 09/06/2010 08:54, Raymond Hettinger a écrit :
next(ifilter(None, d), False)

Good, this is rather short and does the job !...
I should try to use more often this itertools module.

Thanks

Daniel
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,994
Messages
2,570,222
Members
46,810
Latest member
Kassie0918

Latest Threads

Top