Why bool( object )?

S

Steven D'Aprano

Steven D'Aprano said:
for x in a or b or c:
do_something_with(x)

Ugh!!!!

for x in [a,b,c]:
if len(x) > 0:
do_something_with(x)
break

What ugly, wasteful code. And it's *wrong* -- it doesn't do what my code
does.

(1) Why build a list [a, b, c] that you don't need?

(2) Why assume that a, b and c are sequences with a fast __len__ method?
They might be (say) linked lists that take O(N) to calculate the length,
or binary trees that don't even have a length, but can be iterated over.

(3) And your code is wrong. I pass each element of the first non-empty
sequence to do_something_with(). You pass the entire sequence. To do what
my code does, you would need a nested for-loop like this:

for seq in [a,b,c]:
if len(seq) > 0:
for x in seq:
do_something_with(x)
break
 
P

Paul Rubin

Steven D'Aprano said:
(2) Why assume that a, b and c are sequences with a fast __len__ method?
They might be (say) linked lists that take O(N) to calculate the length,
or binary trees that don't even have a length, but can be iterated over.

Why assume they have a bool method? Or a __or__ operator?
for seq in [a,b,c]:
if len(seq) > 0:
for x in seq:
do_something_with(x)
break

Eh.

for seq in [a,b,c]:
if sum(1 for x in imap(do_something_with, seq)) > 0:
break
 
S

Steven D'Aprano

I have never written anything so unbelievable in my life. And I hope I
never will.

I didn't say you did. If anyone thought I was quoting Lawrence's code,
I'd be surprised. It was not my intention to put words into your mouth.

But seeing as you have replied, perhaps you could tell us something.
Given so much you despise using non-bools in truth contexts, how would
you re-write my example to avoid "a or b or c"?

for x in a or b or c:
do_something_with(x)
 
S

Steven D'Aprano

Why assume they have a bool method? Or a __or__ operator?

What programming language are you using?

I'm using Python, where objects don't require either a bool or __or__
method (not operator) to work with the or operator.
.... hasattr(None, '__nonzero__')
False.... hasattr(x, '__nonzero__')
False<object object at 0xb7f3b4f0>

Any object can be used as an operand to the boolean operators.

Eh.

for seq in [a,b,c]:
if sum(1 for x in imap(do_something_with, seq)) > 0:
break

Did I stumble into an Obfuscated Python competition?
 
A

Aaron Brady

I didn't say you did. If anyone thought I was quoting Lawrence's code,
I'd be surprised. It was not my intention to put words into your mouth.

But seeing as you have replied, perhaps you could tell us something.
Given so much you despise using non-bools in truth contexts, how would
you re-write my example to avoid "a or b or c"?

for x in a or b or c:
    do_something_with(x)

I think Hendrik's is the closest so far, but still doesn't iterate
over x:

for t in [a,b,c]:
if t:
for x in t:
do_something_with(x)
break

This is still not right, since Steven's code will raise an exception
if 'a' and 'b' test False, and 'c' is non-iterable.
.... print( x )
....
Traceback (most recent call last):
File said:
.... print( x )
........ print( x )
....
Traceback (most recent call last):
File said:
.... print( x )
....
abc

To mimic it exactly, you'd have to actually convert the first one,
execute 'or' on the other two, since they may have side-effects or
return other values than themselves, and try iterating over the last
one. I think you are looking at an 'ireduce' function, which doesn't
exist in 'itertools' yet.

I don't think it would be very common to write Steven's construction
for arbitrary values of 'a', 'b', and 'c'.
 
P

Paul Rubin

Aaron Brady said:
I think you are looking at an 'ireduce' function, which doesn't
exist in 'itertools' yet.

Nothing is being done with the return value.

sum(1 for x in imap(func, seq))

is enough to force evaluation of func on each element of seq.
 
S

Steven D'Aprano

I didn't say you did. If anyone thought I was quoting Lawrence's code,
I'd be surprised. It was not my intention to put words into your mouth.

But seeing as you have replied, perhaps you could tell us something.
Given so much you despise using non-bools in truth contexts, how would
you re-write my example to avoid "a or b or c"?

for x in a or b or c:
    do_something_with(x)
[...]
I don't think it would be very common to write Steven's construction for
arbitrary values of 'a', 'b', and 'c'.

I don't care about "arbitrary values" for a, b and c. I don't expect a
solution that works for (say) a=None, b=5, c=[]. I'm happy to restrict
the arguments to all be arbitrary sequence-like objects.

I'm even happy for somebody to give a solution with further restrictions,
like "if I know before hand that all three are lists, then I do blah...".
But state your restrictions up front.
 
A

Arnaud Delobelle

Steven D'Aprano said:
On Fri, 01 May 2009 16:30:19 +1200, Lawrence D'Oliveiro wrote:
I have never written anything so unbelievable in my life. And I hope
I never will.

I didn't say you did. If anyone thought I was quoting Lawrence's code,
I'd be surprised. It was not my intention to put words into your mouth.

But seeing as you have replied, perhaps you could tell us something.
Given so much you despise using non-bools in truth contexts, how would
you re-write my example to avoid "a or b or c"?

for x in a or b or c:
    do_something_with(x)
[...]
I don't think it would be very common to write Steven's construction for
arbitrary values of 'a', 'b', and 'c'.

I don't care about "arbitrary values" for a, b and c. I don't expect a
solution that works for (say) a=None, b=5, c=[]. I'm happy to restrict
the arguments to all be arbitrary sequence-like objects.

I'm even happy for somebody to give a solution with further restrictions,
like "if I know before hand that all three are lists, then I do blah...".
But state your restrictions up front.

If a, b, c are names or literals, then I guess you could do this:

for seq in a, b, c:
if seq: break
for x in seq:
do_something_with(x)

I have never been in a situation where I needed something like this,
though.
 

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,815
Messages
2,569,705
Members
45,494
Latest member
KandyFrank

Latest Threads

Top