Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Why bool( object )?

0 views
Skip to first unread message

Aaron Brady

unread,
Apr 28, 2009, 2:11:11 AM4/28/09
to
What is the rationale for considering all instances true of a user-
defined type? Is it strictly a practical stipulation, or is there
something conceptually true about objects?

'''
object.__bool__(self)
If a class defines neither __len__() nor __bool__(), all its instances
are considered true.
'''

This makes it so all objects except False, None, 0, and empty
containers are true by default. I am not convinced that 'if <a
generic object>' should have any meaning; it should probably throw an
exception. Is it part of Python's look and feel or its mentality? Is
it part of the Zen? Certainly other ideal types can't be cast from
generic objects, so why booleans? Is it an ineffable component of the
author's vision for the language? I think that giving arbitrary
syntactic constructs meaning is just space-filler. It's worse than
syntactic sugar, it's semantic sugar. Why not assign meanings willy-
nilly to other random juxtapositions of tokens?

Lie Ryan

unread,
Apr 28, 2009, 2:35:44 AM4/28/09
to
Aaron Brady wrote:
> What is the rationale for considering all instances true of a user-
> defined type?

User-defined objects (or type) can override .__len__() [usually
container types] or .__nonzero__() to make bool() returns False.

> Is it strictly a practical stipulation, or is there
> something conceptually true about objects?

Objects are true unless they define themself as false. The practical
implication is we can do this:

def foo(args = None):
if args:
...

In python all objects are true except: None, False, 0/0L/0.0/0j, empty
sequence or container, and on objects that defines .__len__() or
.__nonzero__() that returns 0 or False.

> '''
> object.__bool__(self)
> If a class defines neither __len__() nor __bool__(), all its instances
> are considered true.
> '''
>
> This makes it so all objects except False, None, 0, and empty
> containers are true by default. I am not convinced that 'if <a
> generic object>' should have any meaning; it should probably throw an
> exception. Is it part of Python's look and feel or its mentality? Is
> it part of the Zen? Certainly other ideal types can't be cast from
> generic objects, so why booleans? Is it an ineffable component of the
> author's vision for the language? I think that giving arbitrary
> syntactic constructs meaning is just space-filler. It's worse than
> syntactic sugar, it's semantic sugar. Why not assign meanings willy-
> nilly to other random juxtapositions of tokens?

It's part of the design decision. In almost all cases (in any language),
a so-called "Design Decision" is rather random and prone to subjective
judgment, just as the decision to make bool(int) returns False only on
0, -1, or for all negative values; whether to make bool(100) and
exception or True; or round() rounds down or up or even-odd; or the use
of brackets vs. indentation; or whether to treat empty list as True or
False.

Chris Rebert

unread,
Apr 28, 2009, 2:54:25 AM4/28/09
to Aaron Brady, pytho...@python.org

I believe the justification is that in the case of objects with
otherwise undefined truth, it effectively serves as a test for
non-None-ness, which makes some sense and is apparently more useful in
practice than throwing an exception.
It was obviously a design decision made by the PSU, probably for
"practicality over purity" reasons; indeed, they could reasonably have
chose to make it throw an exception in such cases, but the current
behavior is also reasonable and justifiable.
For comparison, some other languages use a similar definition of truth
("if you can't show it's false, then it's true"), such as Lisp/Scheme
and Ruby ("if it's not equal to #f/false or nil, then it's true").
Admittedly, it's not a direct comparison since Python has fancier
semantics, but it's somewhat similar.

Cheers,
Chris
--
http://blog.rebertia.com

Aaron Brady

unread,
Apr 28, 2009, 3:09:27 AM4/28/09
to

Whether it's a good feature and whether it's a popular feature are two
different things. (It's not always clear that the former is even real
anyway.)

I'm actually not sure that my question was /entirely/ scientifically
motivated. Perhaps I'm expressing admiration (or maybe envy). Maybe
I want to design a popular language too.

If I was really being scientific, I would have been wondering, what is
the balance of pros and cons of the decision? pros - cons = ? Is
that an objective expression? Are there only measurable quantities in
both operands? If it's a close call, I might not agree, or might not
have followed the same experimental method.

Trivially the answer is, 'the decision maker found sum( pros ) > sum
( cons )'. Many arts and disciplines do guesswork to a degree in
evaluating their 'sum( pros )', so perhaps I should expect a degree of
variation in what the experts all say that quantity is.

On a more idealist's level, perhaps I am asking the outside world
what /my/ evaluation of 'sum( pros )' is. What's yours?

Steven D'Aprano

unread,
Apr 28, 2009, 3:39:51 AM4/28/09
to
On Mon, 27 Apr 2009 23:11:11 -0700, Aaron Brady wrote:

> What is the rationale for considering all instances true of a user-
> defined type? Is it strictly a practical stipulation, or is there
> something conceptually true about objects?

Seven years ago, in an attempt to convince Guido *not* to include
booleans in Python, Laura Creighton wrote a long, detailed post
explaining her opposition.

At the heart of her argument is the observation that Python didn't need
booleans, at least not the ints-in-fancy-hats booleans that we've ended
up with, because Python already made a far more useful and fundamental
distinction: between Something and Nothing.

http://groups.google.com/group/comp.lang.python/msg/2de5e1c8384c0360?hl=en

All objects are either Something or Nothing. The instances of some
classes are always Something, just as the instances of some classes are
always Nothing. By default, instances are Something, unless __nonzero__
returns False, or __len__ returns 0, then they are Nothing.

In a boolean (or truth) context, Something and Nothing behave like True
and False in languages with real booleans:

if obj:
print "I am Something"
else:
print "I am Nothing"


To steal an idiom from Laura: Python has a float-shaped Nothing 0.0, a
list-shaped Nothing [], a dict-shaped Nothing {}, an int-shaped Nothing
0, a singleton Nothing None, and so forth. It also has many corresponding
Somethings.

All bool() does is convert Something or Nothing into a canonical form,
the subclassed ints True and False.

I'm not sure whether Guido ever used the terms Something vs Nothing when
describing Python's truth-testing model, but it is clearly there, at the
heart of Python. Python didn't even get a boolean type until version 2.3.


--
Steven

Lawrence D'Oliveiro

unread,
Apr 28, 2009, 6:10:33 AM4/28/09
to
In message <54cb7f8a-

> What is the rationale for considering all instances true of a user-
> defined type?

It's a stupid idea, and there seem to be instances of users tripping over it
here in comp.lang.python every week.

Colin J. Williams

unread,
Apr 28, 2009, 8:22:01 AM4/28/09
to
Lie Ryan wrote:
> Aaron Brady wrote:
>> What is the rationale for considering all instances true of a user-
>> defined type?
>
> User-defined objects (or type) can override .__len__() [usually
> container types] or .__nonzero__() to make bool() returns False.
>
>> Is it strictly a practical stipulation, or is there
>> something conceptually true about objects?
>
> Objects are true unless they define themself as false. The practical
> implication is we can do this:
>
> def foo(args = None):
> if args:
> ...
>
> In python all objects are true except: None, False, 0/0L/0.0/0j, empty
> sequence or container, and on objects that defines .__len__() or
> ..__nonzero__() that returns 0 or False.

>
>> '''
>> object.__bool__(self)
>> If a class defines neither __len__() nor __bool__(), all its instances
>> are considered true.
>> '''
>>
>> This makes it so all objects except False, None, 0, and empty
>> containers are true by default. I am not convinced that 'if <a
>> generic object>' should have any meaning; it should probably throw an
>> exception. Is it part of Python's look and feel or its mentality? Is
>> it part of the Zen? Certainly other ideal types can't be cast from
>> generic objects, so why booleans? Is it an ineffable component of the
>> author's vision for the language? I think that giving arbitrary
>> syntactic constructs meaning is just space-filler. It's worse than
>> syntactic sugar, it's semantic sugar. Why not assign meanings willy-
>> nilly to other random juxtapositions of tokens?
>
> It's part of the design decision. In almost all cases (in any language),
> a so-called "Design Decision" is rather random and prone to subjective
> judgment, just as the decision to make bool(int) returns False only on
> 0, -1, or for all negative values; whether to make bool(100) and
> exception or True; or round() rounds down or up or even-odd; or the use
> of brackets vs. indentation; or whether to treat empty list as True or
> False.

I'm puzzled by the last sentence:

*** Python 2.6.2 (r262:71605, Apr 14
2009, 22:40:02) [MSC v.1500 32 bit
(Intel)] on win32. ***
>>> bool(0)
False
>>> bool(-1)
True
>>> bool(-100)
True
>>>

Colin W.

Andre Engels

unread,
Apr 28, 2009, 8:35:12 AM4/28/09
to Colin J. Williams, pytho...@python.org
> --
> http://mail.python.org/mailman/listinfo/python-list
>

bool has been defined thus in Python:

False are:
* False
* None
* empty containers, lists etc.
* The number zero

Everything else is true.

-100 is not equal to zero, so its boolean value is True.

--
André Engels, andre...@gmail.com

Gabriel Genellina

unread,
Apr 28, 2009, 12:12:43 PM4/28/09
to pytho...@python.org
En Tue, 28 Apr 2009 09:22:01 -0300, Colin J. Williams <c...@ncf.ca>
escribiᅵ:

>>>> bool(0)
> False
>>>> bool(-1)
> True
>>>> bool(-100)
> True

That's the "design decision". bool(-1) *might* have been False, and
bool(-100) *might* raise an exception. They behave the way they do because
of a conscious decision.

To Aaron: "Programming language design is not a rational science. Most
reasoning about is is at best rationalization of gut feelings, and at
worst plain wrong."
(GvR in python-ideas:
http://groups.google.com/group/python-ideas/msg/ac61f03c32578bae )

--
Gabriel Genellina

Scott David Daniels

unread,
Apr 28, 2009, 12:44:13 PM4/28/09
to
Steven D'Aprano wrote:
> On Mon, 27 Apr 2009 23:11:11 -0700, Aaron Brady wrote:
>... In a boolean (or truth) context, Something and Nothing behave like True

> and False in languages with real booleans:
> if obj:
> print "I am Something"
> else:
> print "I am Nothing"

If you define the short-circuit boolean operators "and" and "or" as
Python does, the idea of "most anything is True" menas you can have
code that does:
v = look('here') or look('there') or look('everywhere') or default

This is a nice idiom, and the "or default" can be used in lots of cases.

--Scott David Daniels
Scott....@Acm.Org

Aaron Brady

unread,
Apr 28, 2009, 2:59:18 PM4/28/09
to
On Apr 28, 2:39 am, Steven D'Aprano

<ste...@REMOVE.THIS.cybersource.com.au> wrote:
> On Mon, 27 Apr 2009 23:11:11 -0700, Aaron Brady wrote:
> > What is the rationale for considering all instances true of a user-
> > defined type?  Is it strictly a practical stipulation, or is there
> > something conceptually true about objects?
>
> Seven years ago, in an attempt to convince Guido *not* to include
> booleans in Python, Laura Creighton wrote a long, detailed post
> explaining her opposition.
>
> At the heart of her argument is the observation that Python didn't need
> booleans, at least not the ints-in-fancy-hats booleans that we've ended
> up with, because Python already made a far more useful and fundamental
> distinction: between Something and Nothing.
>
> http://groups.google.com/group/comp.lang.python/msg/2de5e1c8384c0360?...

>
> All objects are either Something or Nothing. The instances of some
> classes are always Something, just as the instances of some classes are
> always Nothing. By default, instances are Something, unless __nonzero__
> returns False, or __len__ returns 0, then they are Nothing.
>
> In a boolean (or truth) context, Something and Nothing behave like True
> and False in languages with real booleans:
>
> if obj:
>     print "I am Something"
> else:
>     print "I am Nothing"
>
> To steal an idiom from Laura: Python has a float-shaped Nothing 0.0, a
> list-shaped Nothing [], a dict-shaped Nothing {}, an int-shaped Nothing
> 0, a singleton Nothing None, and so forth.

The sound of that metaphor is rather pleasing ('sweet nothings'), but
I'm not so sure that metaphors belong in computer science and
programming. Nothing can't have many shapes. Having no onions is the
same as having no carrots. If the different shapes of nothing don't
compare equal to each other, which they don't, then they aren't all
the same thing in different shapes.

Furthermore, it is awfully presumptuous to give objects a default
'nothing-ness' of 'something'. If anything, they should be nothing by
default. Conversion to other primitives is very picky; why should
Boolean be so tolerant?

Rhodri James

unread,
Apr 28, 2009, 9:22:50 PM4/28/09
to pytho...@python.org
On Tue, 28 Apr 2009 19:59:18 +0100, Aaron Brady <casti...@gmail.com>
wrote:

> The sound of that metaphor is rather pleasing ('sweet nothings'), but
> I'm not so sure that metaphors belong in computer science and
> programming. Nothing can't have many shapes. Having no onions is the
> same as having no carrots.

Not if you need onions but not carrots it isn't!

--
Rhodri James *-* Wildebeeste Herder to the Masses

Steven D'Aprano

unread,
Apr 28, 2009, 10:54:02 PM4/28/09
to
On Tue, 28 Apr 2009 11:59:18 -0700, Aaron Brady wrote:

>> To steal an idiom from Laura: Python has a float-shaped Nothing 0.0, a
>> list-shaped Nothing [], a dict-shaped Nothing {}, an int-shaped Nothing
>> 0, a singleton Nothing None, and so forth.
>
> The sound of that metaphor is rather pleasing ('sweet nothings'), but
> I'm not so sure that metaphors belong in computer science and
> programming.

Programming models the world, it isn't the world. Every model is a
metaphor. You can't get away from metaphors in programming, you can only
hide them and pretend they aren't there.

> Nothing can't have many shapes.

In computing, you can't have a literal "nothing", because EVERYTHING
needs to be stored as a pattern of bits. In practice, for most high-level
languages, those bits are interpreted as a type as well as a value, so
the same bit pattern can mean different things according to what type it
is expected to be. Alternatively, the same information can be represented
in different bit patterns depending on how you interpret those bit
patterns.

So in the context of computer programming, of course you can have nothing
with many "shapes": you have the number 0 represented as a single byte, a
16-bit integer, a 32-bit integer, a long-int or BigNum, a pointer with
address 0, fixed point decimals of various sizes, Binary Coded Decimal, a
rational, a single float 0.0, a double float 0.0, a string of "tally
marks" without any tally, and so on, all of them in big-endian and little-
endian formats.

> Having no onions is the same as having no carrots.

"If you have one onion and I take it away, how many onions do you have
left?"

If you answered "no carrots", I'd consider that a bizarre and unhelpful
answer, and wonder what you possibly thought carrots had to do with my
question.

"Nothing" is not an absolute. "There is no wind" is not the same thing as
"there is no money left in my bank account".


> If the different shapes of nothing don't
> compare equal to each other, which they don't, then they aren't all the
> same thing in different shapes.

Who said they were the same thing?


> Furthermore, it is awfully presumptuous to give objects a default
> 'nothing-ness' of 'something'. If anything, they should be nothing by
> default.

That's a stupid idea.

There are 4,294,967,296 integers that can be represented in 32 bits. Only
one of them represents zero.

The number of possible strings is unlimited (except by physical
limitations, such as the amount of memory available, or the size of the
universe). Again, only one of them is the empty string.

Likewise for sets, lists, tuples, dicts, binary trees, queues, and just
about every data structure you care to name: at most one such instance is
empty, out of a potential infinite number of instances.

Most data represents *useful information* ("Something"), not the absence
of information ("Nothing"). Why on earth would you want to reverse that
presumption?

> Conversion to other primitives is very picky; why should
> Boolean be so tolerant?

Because it is useful and meaningful to ask whether an arbitrary object
represents something or nothing, but it's not useful or meaningful to ask
what integer is equivalent to an arbitrary object.

--
Steven

Bruno Desthuilliers

unread,
Apr 29, 2009, 9:39:38 AM4/29/09
to
Lawrence D'Oliveiro a �crit :

> In message <54cb7f8a-
> fef4-4bf8-805...@d2g2000pra.googlegroups.com>, Aaron Brady wrote:
>
>> What is the rationale for considering all instances true of a user-
>> defined type?
>
> It's a stupid idea,

Nope, it's a very sensible default (given you can redefine the
'nothingness' value of your types instances), specially when the
language doesn't have a proper boolean type (which was the case for
Python until 2.2 or 2.3, can't remember exactly).

> and there seem to be instances of users tripping over it
> here in comp.lang.python every week.

Which is why some users opposed to the introduction of a boolean type in
Python by the time. Please read Steven D'aprano's post upper in this
thread, and follow the provided link. Laura Creighton was alas spot on:
introducing a boolean type only resulted in confusion.

Aahz

unread,
Apr 29, 2009, 10:21:45 AM4/29/09
to
In article <340175e7-b349-4ca2...@v23g2000pro.googlegroups.com>,

Aaron Brady <casti...@gmail.com> wrote:
>
>The sound of that metaphor is rather pleasing ('sweet nothings'), but
>I'm not so sure that metaphors belong in computer science and
>programming.

Well, you won't be a good programmer if you can't wrap your head around
metaphor. All programming is about translating human thought into human
language -- albeit a very special language with (mostly) precise rules.
Repeat: programming languages are human languages.
--
Aahz (aa...@pythoncraft.com) <*> http://www.pythoncraft.com/

"If you think it's expensive to hire a professional to do the job, wait
until you hire an amateur." --Red Adair

Marco Mariani

unread,
Apr 29, 2009, 11:35:28 AM4/29/09
to
Bruno Desthuilliers wrote:

> Lawrence D'Oliveiro a �crit :

>>> What is the rationale for considering all instances true of a user-


>>> defined type?
>>
>> It's a stupid idea,
>
> Nope, it's a very sensible default (given you can redefine the
> 'nothingness' value of your types instances), specially when the
> language doesn't have a proper boolean type (which was the case for
> Python until 2.2 or 2.3, can't remember exactly).

Man, you've given a serious answer to a sarcastic reply to an OP who has
been -- for years -- second in trolliness only to Xah Lee.

Either that, or I have to replace my humor detector.

Aaron Brady

unread,
Apr 29, 2009, 1:23:34 AM4/29/09
to
On Apr 28, 9:54 pm, Steven D'Aprano

<ste...@REMOVE.THIS.cybersource.com.au> wrote:
> On Tue, 28 Apr 2009 11:59:18 -0700, Aaron Brady wrote:
> >> To steal an idiom from Laura: Python has a float-shaped Nothing 0.0, a
> >> list-shaped Nothing [], a dict-shaped Nothing {}, an int-shaped Nothing
> >> 0, a singleton Nothing None, and so forth.
>
> > The sound of that metaphor is rather pleasing ('sweet nothings'), but
> > I'm not so sure that metaphors belong in computer science and
> > programming.
>
> Programming models the world, it isn't the world. Every model is a
> metaphor. You can't get away from metaphors in programming, you can only
> hide them and pretend they aren't there.

I was not aware that the intended use for 'True' was 'Something'. I
thought it merely signified membership in a predicate or relation.
'GreaterThan( 3, 2 )', so '3> 2== True'. You might argue that numbers
are metaphors for the world, since they are external to causality,
have no temperature, etc., and likewise with logical predicates. But
just because True is one metaphor, doesn't mean it is every metaphor.
Is casting to a boolean a metaphor for a metaphor?

Mathematically, 'bool' injects mathematical objects into the set
{ True, False }. I would say it's a stretch to say that the empty
list maps to the True value, and non-empty lists map to the False
value. Mathematically, there's no reason to choose that mapping as
the natural meaning and definition over any other, say 'list( x ) iff
len( list( x ) )% 2'. (Some shells, I understand, suppose that there
are multiple ways to fail, while others suppose that there are
multiple ways to succeed.) In programming practice, there is a
frequent division between empty lists and non-empty lists, so the
author chose to map one case to one value, and the other case to the
other.

> > Nothing can't have many shapes.
>
> In computing, you can't have a literal "nothing", because EVERYTHING
> needs to be stored as a pattern of bits.

Correct... until memory gates can self-destruct. <cackle>

The fact that bool( [] ) == bool( {} ). Merely that 'f( x )== f( y )'
does not imply that 'x== y'. I am not arguing that '[]== {}', and I'm
pretty sure you aren't either. However, x and y do form an
equivalence class under 'f', IIRC.

If you ask of (blank), 'Is there anything?', which is what you state
the 'bool' function means to do, there are only two answers: 'Yes,
there is something', and 'No, there is nothing'.

> > Furthermore, it is awfully presumptuous to give objects a default
> > 'nothing-ness' of 'something'.  If anything, they should be nothing by
> > default.  
>
> That's a stupid idea.

[argument] snip

Fine, withdrawn. They shouldn't have one.

> > Conversion to other primitives is very picky; why should
> > Boolean be so tolerant?
>
> Because it is useful and meaningful to ask whether an arbitrary object
> represents something or nothing, but it's not useful or meaningful to ask
> what integer is equivalent to an arbitrary object.

It's more common for it to make sense to divide a set into two pieces
than it is to divide it into N pieces, the cardinality of the
integers. But that doesn't make the presumed implementation 'return
True' for an entire type.

I think the closest you could come would be to try the '__len__'
method, and raise an exception if there isn't one. But if '__len__'
is defined, then there is also a mapping from the type into the
integers. By your logic, 'int( object )' should default to '__len__'
as well, since the mapping is defined!

The 'bool' function means to ask, 'What Boolean value is this object
most like?'. The object's type should ascertain something about the
object, and answer. But that is not what happens. Python's
implementation ignores the object completely, and answers blindly.

Steven D'Aprano

unread,
Apr 29, 2009, 8:29:33 PM4/29/09
to
On Wed, 29 Apr 2009 17:35:28 +0200, Marco Mariani wrote:

> Bruno Desthuilliers wrote:
>
>> Lawrence D'Oliveiro a écrit :

Aaron (castironpi) certainly used to be a major troll, but he got better.
I know, I know, sometimes it's hard to tell if he's trolling or just
engaging in flights of fancy, but I think it's mostly the later.

Lawrence's reply wasn't sarcastic -- he really does think that having
every object be meaningful in a boolean context is stupid.

I think he's not just wrong, but badly wrong. To me, "if bool(x):" is
barely better than "if bool(x) == True:", which in turn is not much
better than "if (bool(x) == True) == True:".

The reason why Lawrence's insistence is so badly wrong becomes more
apparent if you look at what you can do with boolean contexts other than
simple `if` tests. Compare:


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


versus:


if len(a) > 0:
temp = a
elif len(b) > 0:
temp = b
elif len(c) > 0:
temp = c
for x in temp:
do_something_with(x)


--
Steven

r

unread,
Apr 29, 2009, 9:56:22 AM4/29/09
to
On Apr 28, 7:22 am, "Colin J. Williams" <c...@ncf.ca> wrote:
> Lie Ryan wrote:
>
> I'm puzzled by the last sentence:
>
> *** Python 2.6.2 (r262:71605, Apr 14
> 2009, 22:40:02) [MSC v.1500 32 bit
> (Intel)] on win32. ***
>
> >>> bool(0)
> False
> >>> bool(-1)
> True
> >>> bool(-100)
> True
>
> Colin W.

What's wrong with "Lie Ryan" living up to his name? :)

JanC

unread,
Apr 30, 2009, 6:41:14 PM4/30/09
to
Steven D'Aprano wrote:

> There are 4,294,967,296 integers that can be represented in 32 bits. Only
> one of them represents zero.

Or you can even define it as not including zero... ;)


--
JanC

Lawrence D'Oliveiro

unread,
May 1, 2009, 12:30:19 AM5/1/09
to
In message <pan.2009.04...@REMOVE.THIS.cybersource.com.au>, Steven
D'Aprano wrote:

> The reason why Lawrence's insistence is so badly wrong becomes more
> apparent if you look at what you can do with boolean contexts other than
> simple `if` tests. Compare:
>
>
> for x in a or b or c:
> do_something_with(x)
>
>
> versus:
>
>
> if len(a) > 0:
> temp = a
> elif len(b) > 0:
> temp = b
> elif len(c) > 0:
> temp = c
> for x in temp:
> do_something_with(x)

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

Paul Rubin

unread,
May 1, 2009, 3:22:22 AM5/1/09
to
Steven D'Aprano <ste...@REMOVE.THIS.cybersource.com.au> writes:
> 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

Steven D'Aprano

unread,
May 1, 2009, 4:33:08 AM5/1/09
to

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

--
Steven

Paul Rubin

unread,
May 1, 2009, 4:56:50 AM5/1/09
to
Steven D'Aprano <st...@REMOVE-THIS-cybersource.com.au> writes:
> (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

Hendrik van Rooyen

unread,
May 1, 2009, 5:05:08 AM5/1/09
to pytho...@python.org
"Paul Rubin" <http://phr...@NOSPAM.invalid> wrote:


> Steven D'Aprano <st...@source.com.au> writes:
> > 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
>
Ugh!!!!

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

:-)

- Hendrik

Steven D'Aprano

unread,
May 1, 2009, 5:30:21 AM5/1/09
to
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)

--
Steven

Steven D'Aprano

unread,
May 1, 2009, 5:44:23 AM5/1/09
to
On Fri, 01 May 2009 01:56:50 -0700, Paul Rubin wrote:

> Steven D'Aprano <st...@REMOVE-THIS-cybersource.com.au> writes:
>> (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?

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, '__or__') or hasattr(None, '__bool__') or \
... hasattr(None, '__nonzero__')
False
>>>
>>> x = object()
>>> hasattr(x, '__or__') or hasattr(x, '__bool__') or \
... hasattr(x, '__nonzero__')
False
>>>
>>> None or x
<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?


--
Steven

Aaron Brady

unread,
May 1, 2009, 6:03:30 PM5/1/09
to
On May 1, 4:30 am, Steven D'Aprano <st...@REMOVE-THIS-

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.

>>> for x in 0 or 0 or 0:
... print( x )
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable
>>> for x in 0 or 0 or []:
... print( x )
...
>>> for x in 0 or 0 or 1:
... print( x )
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable
>>> for x in ['abc'] or 0 or 0:
... 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'.

Paul Rubin

unread,
May 1, 2009, 6:47:49 PM5/1/09
to
Aaron Brady <casti...@gmail.com> writes:
> 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.

Steven D'Aprano

unread,
May 1, 2009, 9:47:32 PM5/1/09
to
On Fri, 01 May 2009 15:03:30 -0700, Aaron Brady wrote:

> On May 1, 4:30 am, Steven D'Aprano <st...@REMOVE-THIS-
> cybersource.com.au> wrote:
>> 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.


--
Steven

Arnaud Delobelle

unread,
May 2, 2009, 4:23:58 AM5/2/09
to
Steven D'Aprano <st...@REMOVE-THIS-cybersource.com.au> writes:

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.
--
Arnaud

0 new messages