By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
432,650 Members | 1,785 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 432,650 IT Pros & Developers. It's quick & easy.

question about True values

P: n/a
I'm a little confused. Why doesn't s evaluate to True in the first part,
but it does in the second? Is the first statement something different?
>>s = 'hello'
s == True
False
>>if s:
print 'hi'
hi
>>>
Thanks.
Oct 25 '06 #1
Share this Question
Share on Google+
90 Replies


P: n/a
John Salerno <jo******@NOSPAMgmail.comwrites:
I'm a little confused. Why doesn't s evaluate to True in the first
part, but it does in the second? Is the first statement something
different?
No. True and False are boolean values, where booleans are a different
data type from strings, just like strings are different from integers.
>>if s:
print 'hi'

converts s to a boolean during evaluation. That is, it's the same as

if bool(s): print 'hi'

bool(s) is a function that converts s to a bool. If s is a string,
bool(s) is true if s is nonempty, false otherwise.

A comparable thing with integers: suppose

x = 3.1

then "x == 3" is false, but "int(x) == 3" is true.
Oct 25 '06 #2

P: n/a

JohnI'm a little confused. Why doesn't s evaluate to True in the first
Johnpart, but it does in the second? Is the first statement something
Johndifferent?
>>s = 'hello'
s == True
False
>>if s:
... print 'hi'
hi

s is not equal to the boolean object True, but it also doesn't evaluate to
the string class's "nil" value. Each of the builtin types has such an
"empty" or "nil" value:

string ""
list []
tuple ()
dict {}
int 0
float 0.0
complex 0j
set set()

Any other value besides the above will compare as "not false".

Skip
Oct 25 '06 #3

P: n/a

John Salerno wrote:
I'm a little confused. Why doesn't s evaluate to True in the first part,
but it does in the second? Is the first statement something different?
>>s = 'hello'
>>s == True
False
>>if s:
print 'hi'
hi
>>>

Thanks.
Excellent question! This should help:
>>s = "Hello"
s
'Hello'
>>bool(s)
True
>>s == True
False

The value of s is not equal to the value of True. But, the *boolean*
value of s is True, since it is not 0 or an empty string. The python
'if' statement evaluates the boolean value of the condition expression.

Oct 25 '06 #4

P: n/a

Paul Rubin wrote:
John Salerno <jo******@NOSPAMgmail.comwrites:
I'm a little confused. Why doesn't s evaluate to True in the first
part, but it does in the second? Is the first statement something
different?

No. True and False are boolean values, where booleans are a different
data type from strings, just like strings are different from integers.
>>if s:
print 'hi'

converts s to a boolean during evaluation. That is, it's the same as

if bool(s): print 'hi'

bool(s) is a function that converts s to a bool. If s is a string,
bool(s) is true if s is nonempty, false otherwise.

A comparable thing with integers: suppose

x = 3.1

then "x == 3" is false, but "int(x) == 3" is true.
But then why is 3.0 == 3 true? They are different types.

Oct 25 '06 #5

P: n/a
Paul Rubin wrote:
No. True and False are boolean values, where booleans are a different
data type from strings, just like strings are different from integers.
>>if s:
print 'hi'

converts s to a boolean during evaluation.

Oh!!! I get it now! I was thinking that

if s

was the same as

if s == True

because I know sometimes you can write if statements this way (though
it's wordy). But what I didn't realize was that in the cases I was
thinking of, 's' was an expression that evaluated to a boolean value,
not an actual value of some other type!

So I suppose

if (10 5)

would be the same as

if (10 5) == True

because (10 5) does evaluate to "True".
Oct 25 '06 #6

P: n/a
"John Coleman" <jc******@franciscan.eduwrites:
then "x == 3" is false, but "int(x) == 3" is true.
But then why is 3.0 == 3 true? They are different types.
The 3 gets converted to float, like when you say

x = 3.1 + 3

the result is 6.1.
Oct 25 '06 #7

P: n/a
John Salerno <jo******@NOSPAMgmail.comwrites:
if (10 5)
would be the same as
if (10 5) == True
Yes.
Oct 25 '06 #8

P: n/a
John Salerno wrote:
I'm a little confused. Why doesn't s evaluate to True in the first part,
but it does in the second? Is the first statement something different?
>>s = 'hello'
>>s == True
False
>>if s:
print 'hi'
hi
>>>
They are, indeed, quite different things. Finding the truth value of an object
is not the same thing as testing if the object is equal to the object True. When
people use the phrase "evaluate to True" in the context of an if: statement,
they mean that the truth value of the object (found using the special method
..__nonzero__()) is True, not that it is equal to True.

It's a bit of an abuse on the English language, but what isn't in software?

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco

Oct 25 '06 #9

P: n/a
John Salerno wrote:
I'm a little confused. Why doesn't s evaluate to True in the first part,
but it does in the second? Is the first statement something different?
>>s = 'hello'
>>s == True
False
>>if s:
print 'hi'
"true" != "True". comparing a value to another value isn't the same
thing as interpreting a value in a specific context:

http://docs.python.org/lib/truth.html

</F>

Oct 25 '06 #10

P: n/a
I'm a little confused. Why doesn't s evaluate to True in the first part,
but it does in the second? Is the first statement something different?
>>s = 'hello'
>>s == True
False
>>if s:
print 'hi'
The "if s" does an implicit (yeah, I know, "explicit is better
than implicit") conversion to bool, like

if bool(s):

And as such, you'll find that

bool(s) == True

You can learn more at

http://docs.python.org/lib/truth.html

where you'll see that it's not really exactly a bool() call, but
that strings are a special case listed here. And if not, they
also have a __len__ method which would return zero/non-zero in
the even that strings weren't handled, making the "actual" test
(if strings weren't special-cased)

(s.__len__() <0) == True

-tkc


Oct 25 '06 #11

P: n/a
John Coleman wrote:
But then why is 3.0 == 3 true? They are different types.
Good question. Does one type get converted to the other automatically?
That's all I can think of...
Oct 25 '06 #12

P: n/a
Robert Kern wrote:
They are, indeed, quite different things. Finding the truth value of an
object is not the same thing as testing if the object is equal to the
object True.
Yeah, I had this in the back of my mind, but I was thinking that this
test would be written as

if s is True

And I know that one is very different from the others.
Oct 25 '06 #13

P: n/a
So I suppose
>
if (10 5)

would be the same as

if (10 5) == True

because (10 5) does evaluate to "True".
Yes...and similarly,

if ((10 5) == True) == True

for the same reason...as does

if (((10 5) == True) == True) == True

as does... :*)

-tkc

Oct 25 '06 #14

P: n/a

Paul Rubin wrote:
"John Coleman" <jc******@franciscan.eduwrites:
then "x == 3" is false, but "int(x) == 3" is true.
But then why is 3.0 == 3 true? They are different types.

The 3 gets converted to float, like when you say

x = 3.1 + 3

the result is 6.1.
Yes - it just seems that there isn't a principled reason for implicitly
converting 3 to 3.0 in 3.0 == 3 but not implicitly converting "cat" to
boolean in "cat" == true. There is something to be said about SML's
rigourous approach where 3.0 = 3 isn't even allowed since it is
considered ill-typed. Nevertheless, it is doubtlessly convientent to be
able to compare integers and doubles directly in the natural way and
there is little practical reason to compare a string with a truth value
so Python's solution does have common sense on its side.

Oct 25 '06 #15

P: n/a
sk**@pobox.com schrieb:
the string class's "nil" value. Each of the builtin types has such an
"empty" or "nil" value:

string ""
list []
tuple ()
dict {}
int 0
float 0.0
complex 0j
set set()

Any other value besides the above will compare as "not false".
This list of values that are considered false is incomplete,
though. Four obvious omissions are

long 0L
unicode u""
bool False
NoneType None

Not-so-obviously, arbitrary user-defined values can also be
treated as false: If they implement __nonzero__, they are
false if False is returned from __nonzero__; otherwise,
if they implement __len__, they are false if 0 is returned
from __len__. Under these rules, array.array objects can
also be false, as can UserList and UserDict objects.

Regards,
Martin
Oct 25 '06 #16

P: n/a
John Coleman schrieb:
Yes - it just seems that there isn't a principled reason for implicitly
converting 3 to 3.0 in 3.0 == 3 but not implicitly converting "cat" to
boolean in "cat" == true.
Sure there is: equality should be transitive. So while we have
3 == 3L == 3.0 == 3.0+0j
and can therefore imply that 3 == 3.0+0j, we should not get
5 == True == ["foo"]
and therefore imply that 5 == ["foo"].

The phenomenon really exists only for numeric types (that two
values of different types still represent the same "thing"),
so it's not surprising that this doesn't readily extend to
other types.

In Python, there are only very few similar cases: byte strings
and unicode strings sometimes compare equal (but, since 2.5,
don't compare unequal very often); lists and tuples could be
considered to have equal values, but don't actually do compare
equal.

Regards,
Martin
Oct 25 '06 #17

P: n/a

Martin v. Löwis wrote:
John Coleman schrieb:
Yes - it just seems that there isn't a principled reason for implicitly
converting 3 to 3.0 in 3.0 == 3 but not implicitly converting "cat"to
boolean in "cat" == true.

Sure there is: equality should be transitive. So while we have
3 == 3L == 3.0 == 3.0+0j
and can therefore imply that 3 == 3.0+0j, we should not get
5 == True == ["foo"]
and therefore imply that 5 == ["foo"].

The phenomenon really exists only for numeric types (that two
values of different types still represent the same "thing"),
so it's not surprising that this doesn't readily extend to
other types.

In Python, there are only very few similar cases: byte strings
and unicode strings sometimes compare equal (but, since 2.5,
don't compare unequal very often); lists and tuples could be
considered to have equal values, but don't actually do compare
equal.

Regards,
Martin
Very good point, though one could argue perhaps that when one is
comparing an object with a truth value then one is implicitly asking
for the truth value of that object i.e. how it would function if used
in an if statement, etc. This would make code like 'if s: ' equivalent
to 'if s == True:' with a possible gain in readability. But - as you
demonstrate the cost of that (minimal) gain in readability would be too
high. In any event - I think it is mostly bad style to use a
non-boolean variable in 'if s:' - it reminds me too much of obscure C
code (though others might disagree).

-John Coleman

Oct 25 '06 #18

P: n/a
Martin v. Löwis wrote:
sk**@pobox.com schrieb:
the string class's "nil" value. Each of the builtin types has such an
"empty" or "nil" value:

string ""
list []
tuple ()
dict {}
int 0
float 0.0
complex 0j
set set()

Any other value besides the above will compare as "not false".

This list of values that are considered false is incomplete,
though. Four obvious omissions are

long 0L
unicode u""
bool False
NoneType None

Not-so-obviously, arbitrary user-defined values can also be
treated as false: If they implement __nonzero__, they are
false if False is returned from __nonzero__; otherwise,
if they implement __len__, they are false if 0 is returned
from __len__. Under these rules, array.array objects can
also be false, as can UserList and UserDict objects.
A notable exception are numarray arrays (probably true for numpy too, I
haven't tested it though):
>>from numarray import array
bool(array([1,2]))
Traceback (most recent call last):
File "<stdin>", line 1, in ?
RuntimeError: An array doesn't make sense as a truth value. Use any(a)
or all(a).

George

Oct 25 '06 #19

P: n/a
In article <11**********************@f16g2000cwb.googlegroups .com>,
"John Coleman" <jc******@franciscan.eduwrote:
Very good point, though one could argue perhaps that when one is
comparing an object with a truth value then one is implicitly asking
for the truth value of that object
On the contrary -- since there is normally no need to ever
compare an object with a truth value, then I would interpret
this usage as an attempt to distinguish True or False from
other objects in general. Some kind of placeholders for
missing values, who knows. I'm not saying it's a great idea,
but it could work in recent versions of Python.
This would make code like 'if s: ' equivalent
to 'if s == True:' with a possible gain in readability. But - as you
demonstrate the cost of that (minimal) gain in readability would be too
high. In any event - I think it is mostly bad style to use a
non-boolean variable in 'if s:' - it reminds me too much of obscure C
code (though others might disagree).
Others will indeed disagree. I don't think you'll find
much support for this position. But it's not as bad as
your notion that "if s == True", where s is not a boolean
object, might represent a gain in readability. That really
redefines readability.

Donn Cave, do**@u.washington.edu
Oct 25 '06 #20

P: n/a
sk**@pobox.com wrote:
JohnI'm a little confused. Why doesn't s evaluate to True in the first
Johnpart, but it does in the second? Is the first statement something
Johndifferent?
>>s = 'hello'
>>s == True
False
>>if s:
... print 'hi'
hi

s is not equal to the boolean object True, but it also doesn't evaluate to
the string class's "nil" value. Each of the builtin types has such an
"empty" or "nil" value:

string ""
list []
tuple ()
dict {}
int 0
float 0.0
complex 0j
set set()

Any other value besides the above will compare as "not false".
And today's question for the novices is: which Python type did Skip miss
from the above list?

regards
Steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC/Ltd http://www.holdenweb.com
Skype: holdenweb http://holdenweb.blogspot.com
Recent Ramblings http://del.icio.us/steve.holden

Oct 25 '06 #21

P: n/a
John Coleman wrote:
Martin v. Löwis wrote:
>>John Coleman schrieb:
>>>Yes - it just seems that there isn't a principled reason for implicitly
converting 3 to 3.0 in 3.0 == 3 but not implicitly converting "cat" to
boolean in "cat" == true.

Sure there is: equality should be transitive. So while we have
3 == 3L == 3.0 == 3.0+0j
and can therefore imply that 3 == 3.0+0j, we should not get
5 == True == ["foo"]
and therefore imply that 5 == ["foo"].

The phenomenon really exists only for numeric types (that two
values of different types still represent the same "thing"),
so it's not surprising that this doesn't readily extend to
other types.

In Python, there are only very few similar cases: byte strings
and unicode strings sometimes compare equal (but, since 2.5,
don't compare unequal very often); lists and tuples could be
considered to have equal values, but don't actually do compare
equal.

Regards,
Martin


Very good point, though one could argue perhaps that when one is
comparing an object with a truth value then one is implicitly asking
for the truth value of that object i.e. how it would function if used
in an if statement, etc. This would make code like 'if s: ' equivalent
to 'if s == True:' with a possible gain in readability. But - as you
demonstrate the cost of that (minimal) gain in readability would be too
high. In any event - I think it is mostly bad style to use a
non-boolean variable in 'if s:' - it reminds me too much of obscure C
code (though others might disagree).
That's such a well-used (even though sometime abused) Ptyhon idiom that
it's never going to go away.

regards
Steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC/Ltd http://www.holdenweb.com
Skype: holdenweb http://holdenweb.blogspot.com
Recent Ramblings http://del.icio.us/steve.holden

Oct 25 '06 #22

P: n/a
Paul Rubin wrote:
John Salerno <jo******@NOSPAMgmail.comwrites:
>>if (10 5)
would be the same as
if (10 5) == True


Yes.
Though it would be bad style to write it in the latter way, not to
mention less efficient.

regards
Steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC/Ltd http://www.holdenweb.com
Skype: holdenweb http://holdenweb.blogspot.com
Recent Ramblings http://del.icio.us/steve.holden

Oct 25 '06 #23

P: n/a
On 2006-10-25, John Coleman <jc******@franciscan.eduwrote:
>
Paul Rubin wrote:
>John Salerno <jo******@NOSPAMgmail.comwrites:
I'm a little confused. Why doesn't s evaluate to True in the first
part, but it does in the second? Is the first statement something
different?

No. True and False are boolean values, where booleans are a different
data type from strings, just like strings are different from integers.
> >>if s:
print 'hi'

converts s to a boolean during evaluation. That is, it's the same as

if bool(s): print 'hi'

bool(s) is a function that converts s to a bool. If s is a string,
bool(s) is true if s is nonempty, false otherwise.

A comparable thing with integers: suppose

x = 3.1

then "x == 3" is false, but "int(x) == 3" is true.

But then why is 3.0 == 3 true? They are different types.
3 gets promoted to a float. In most (all?) current
implementations, that turns out to be 3.0, but that's not
guaranteed.

It could be argued that promotion of integer types to floats
and shorter integers to longer integers is "a bad thing" in
what's supposed to be a strictly typed language. But, it's one
of those things that done that way because it's always been
done that way.

While it does make life simpler in many cases, it's also a
source of bugs in others.

--
Grant Edwards grante Yow! Why is it that when
at you DIE, you can't take
visi.com your HOME ENTERTAINMENT
CENTER with you??
Oct 25 '06 #24

P: n/a
George Sakkis wrote:
Martin v. Löwis wrote:
>Not-so-obviously, arbitrary user-defined values can also be
treated as false: If they implement __nonzero__, they are
false if False is returned from __nonzero__; otherwise,
if they implement __len__, they are false if 0 is returned
from __len__. Under these rules, array.array objects can
also be false, as can UserList and UserDict objects.

A notable exception are numarray arrays (probably true for numpy too, I
haven't tested it though):
>>>from numarray import array
bool(array([1,2]))
Traceback (most recent call last):
File "<stdin>", line 1, in ?
RuntimeError: An array doesn't make sense as a truth value. Use any(a)
or all(a).
numpy also has this behavior. Numeric yielded to the temptation to guess any(a)
in the face of this ambiguity. Much buggy code was written as a result.

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco

Oct 25 '06 #25

P: n/a
Steve Holden <st***@holdenweb.comwrites:
sk**@pobox.com wrote:
s is not equal to the boolean object True, but it also doesn't
evaluate to the string class's "nil" value. Each of the builtin
types has such an "empty" or "nil" value:

string ""
list []
tuple ()
dict {}
int 0
float 0.0
complex 0j
set set()

Any other value besides the above will compare as "not false".

And today's question for the novices is: which Python type did Skip
miss from the above list?
bool False

--
\ "[The RIAA] have the patience to keep stomping. They're playing |
`\ whack-a-mole with an infinite supply of tokens." -- kennon, |
_o__) http://kuro5hin.org/ |
Ben Finney

Oct 26 '06 #26

P: n/a

"Steve Holden" <st***@holdenweb.comwrote in message
news:eh**********@sea.gmane.org...
>the string class's "nil" value. Each of the builtin types has such an
"empty" or "nil" value:

string ""
list []
tuple ()
dict {}
int 0
float 0.0
complex 0j
set set()

Any other value besides the above will compare as "not false".

And today's question for the novices is: which Python type did Skip miss
from the above list?
more that one:

0L
decimal.Decimal(0) # is decimal.Decimal('0'), also
u''
array.array('c') # or any other typecode, I suspect, without initializer

Terry Jan Reedy

Oct 26 '06 #27

P: n/a
At Wednesday 25/10/2006 22:29, Terry Reedy wrote:
the string class's "nil" value. Each of the builtin types has such an
"empty" or "nil" value:

string ""
list []
tuple ()
dict {}
int 0
float 0.0
complex 0j
set set()

Any other value besides the above will compare as "not false".
And today's question for the novices is: which Python type did Skip miss
from the above list?

more that one:

0L
decimal.Decimal(0) # is decimal.Decimal('0'), also
u''
array.array('c') # or any other typecode, I suspect, without initializer
Just for fun:
buffer('')
frozenset()
iter(())
xrange(0)

--
Gabriel Genellina
Softlab SRL

__________________________________________________
Correo Yahoo!
Espacio para todos tus mensajes, antivirus y antispam ¡gratis!
¡Abrí tu cuenta ya! - http://correo.yahoo.com.ar
Oct 26 '06 #28

P: n/a
Gabriel Genellina wrote:
At Wednesday 25/10/2006 22:29, Terry Reedy wrote:
>the string class's "nil" value. Each of the builtin types has such an
"empty" or "nil" value:

string ""
list []
tuple ()
dict {}
int 0
float 0.0
complex 0j
set set()

Any other value besides the above will compare as "not false".
And today's question for the novices is: which Python type did Skip
miss
from the above list?

more that one:

0L
decimal.Decimal(0) # is decimal.Decimal('0'), also
u''
array.array('c') # or any other typecode, I suspect, without initializer


Just for fun:
buffer('')
frozenset()
iter(())
xrange(0)
There's still a very obvious omission ...

regards
Steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC/Ltd http://www.holdenweb.com
Skype: holdenweb http://holdenweb.blogspot.com
Recent Ramblings http://del.icio.us/steve.holden

Oct 26 '06 #29

P: n/a
Steve Holden <st***@holdenweb.comwrites:
sk**@pobox.com wrote:
Each of the builtin types has such an "empty" or "nil" value:

string ""
list []
tuple ()
dict {}
int 0
float 0.0
complex 0j
set set()

Any other value besides the above will compare as "not false".

And today's question for the novices is: which Python type did Skip
miss from the above list?
Is it cheating if I read this page:

<URL:http://docs.python.org/lib/truth.html>

--
\ "I always wanted to be somebody. I see now that I should have |
`\ been more specific." -- Lily Tomlin |
_o__) |
Ben Finney

Oct 26 '06 #30

P: n/a
Steve Holden <st***@holdenweb.comwrites:
Gabriel Genellina wrote:
Just for fun:
buffer('')
frozenset()
iter(())
xrange(0)
I get that iter(()) is True (Python 2.3.4).
[Steve:] There's still a very obvious omission ...
Hehehe...
Oct 26 '06 #31

P: n/a

John Coleman wrote:
Paul Rubin wrote:
"John Coleman" <jc******@franciscan.eduwrites:
then "x == 3" is false, but "int(x) == 3" is true.
But then why is 3.0 == 3 true? They are different types.
The 3 gets converted to float, like when you say

x = 3.1 + 3

the result is 6.1.

Yes - it just seems that there isn't a principled reason for implicitly
converting 3 to 3.0 in 3.0 == 3 but not implicitly converting "cat" to
boolean in "cat" == true.
Because being true is not the same as equaling True. == is a test for
equaling, not being.
Carl Banks

Oct 26 '06 #32

P: n/a
"Robert Kern" <ro*********@gmail.com wrote:
8<--------------------------------------
It's a bit of an abuse on the English language, but what isn't in software?
jumps used not to be

- Hendrik

Oct 26 '06 #33

P: n/a

Donn Cave wrote:
In article <11**********************@f16g2000cwb.googlegroups .com>,
"John Coleman" <jc******@franciscan.eduwrote:
Very good point, though one could argue perhaps that when one is
comparing an object with a truth value then one is implicitly asking
for the truth value of that object

On the contrary -- since there is normally no need to ever
compare an object with a truth value, then I would interpret
this usage as an attempt to distinguish True or False from
other objects in general. Some kind of placeholders for
missing values, who knows. I'm not saying it's a great idea,
but it could work in recent versions of Python.
This would make code like 'if s: ' equivalent
to 'if s == True:' with a possible gain in readability. But - as you
demonstrate the cost of that (minimal) gain in readability would be too
high. In any event - I think it is mostly bad style to use a
non-boolean variable in 'if s:' - it reminds me too much of obscure C
code (though others might disagree).

Others will indeed disagree. I don't think you'll find
much support for this position. But it's not as bad as
your notion that "if s == True", where s is not a boolean
object, might represent a gain in readability. That really
redefines readability.

Donn Cave, do**@u.washington.edu
As far as readability goes - most computer languages have a surface
syntax which is (by design) vaguely similiar to the syntax of a natural
language like English. Thus statements roughly correspond to sentences.
For example, you can see a subject-verb-object pattern in "x=3". Given
a genuinely boolean construct like x < 2, "if x < 2:" *sounds* right to
a human reader. Similarly, given a good boolean variable with a
descriptive name like "found", the fragment "if found:" sounds ok. But
- given a non-boolean variable like "product_name" - writing "if
product_name:" sounds (to my ears) a little jarring - it sounds like a
sentence fragment. It's like saying "If Bob" - If Bob *what*? Goes to
the store? answers the telephone? Finish the damn thought! Now, if you
were to (from some strange reason) use "product_name" as if it were a
truth value then (to my ears) it would both make your intentions more
clear and sound less fragmentary if you could say "if product_name ==
True:". When you use "product_name" as the condition of an if statement
then in that context it is *functioning* as a truth value so (naively)
what could be wrong with comparing it to a truth value? I don't
advocate any change in Python here - just pointing out that the idea of
allowing "if s:" and "if s == True:" to be always equivalent in the
interest of readability isn't *that* strange. It doesn't constitute a
redefinition of readability.

As far as using non-booleans as conditions - I just think that if you
want a certain block of code to be executed only if, for example, a
list is non-empty, why not *say* so? I think "if my_list != []:" just
reads better than "if my_list:". I would think that my preferences
there mesh with "Explicit is better than implicit" but apparently not.

I'm just starting out with Python with most of my programming in recent
years being in various dialects of Visual Basic (which probably
explains a lot). What attracts me to Python so far is the cool slice
operations, the iterators, the libraries and the convience of
programming in a REPL environment. So far, the ability to use "cat" as
a part-time substitute for True just strikes me as a curiousity - but
maybe that will change with time.

-John Coleman

Oct 26 '06 #34

P: n/a
John Coleman wrote:
Donn Cave wrote:
>>In article <11**********************@f16g2000cwb.googlegroups .com>,
"John Coleman" <jc******@franciscan.eduwrote:

>>>Very good point, though one could argue perhaps that when one is
comparing an object with a truth value then one is implicitly asking
for the truth value of that object

On the contrary -- since there is normally no need to ever
compare an object with a truth value, then I would interpret
this usage as an attempt to distinguish True or False from
other objects in general. Some kind of placeholders for
missing values, who knows. I'm not saying it's a great idea,
but it could work in recent versions of Python.

>>>This would make code like 'if s: ' equivalent
to 'if s == True:' with a possible gain in readability. But - as you
demonstrate the cost of that (minimal) gain in readability would be too
high. In any event - I think it is mostly bad style to use a
non-boolean variable in 'if s:' - it reminds me too much of obscure C
code (though others might disagree).

Others will indeed disagree. I don't think you'll find
much support for this position. But it's not as bad as
your notion that "if s == True", where s is not a boolean
object, might represent a gain in readability. That really
redefines readability.

Donn Cave, do**@u.washington.edu


As far as readability goes - most computer languages have a surface
syntax which is (by design) vaguely similiar to the syntax of a natural
language like English. Thus statements roughly correspond to sentences.
For example, you can see a subject-verb-object pattern in "x=3". Given
a genuinely boolean construct like x < 2, "if x < 2:" *sounds* right to
a human reader. Similarly, given a good boolean variable with a
descriptive name like "found", the fragment "if found:" sounds ok. But
- given a non-boolean variable like "product_name" - writing "if
product_name:" sounds (to my ears) a little jarring - it sounds like a
sentence fragment. It's like saying "If Bob" - If Bob *what*? Goes to
the store? answers the telephone? Finish the damn thought! Now, if you
were to (from some strange reason) use "product_name" as if it were a
truth value then (to my ears) it would both make your intentions more
clear and sound less fragmentary if you could say "if product_name ==
True:". When you use "product_name" as the condition of an if statement
then in that context it is *functioning* as a truth value so (naively)
what could be wrong with comparing it to a truth value? I don't
advocate any change in Python here - just pointing out that the idea of
allowing "if s:" and "if s == True:" to be always equivalent in the
interest of readability isn't *that* strange. It doesn't constitute a
redefinition of readability.
Yes, but you're talking about *your* ears there. I was pointing out, as
others have, that "if product_name" is such a deeply-ingrained Python
idiom that you can use how natural it "sounds" to you as a measure of
your progress in the language.
As far as using non-booleans as conditions - I just think that if you
want a certain block of code to be executed only if, for example, a
list is non-empty, why not *say* so? I think "if my_list != []:" just
reads better than "if my_list:". I would think that my preferences
there mesh with "Explicit is better than implicit" but apparently not.
Maybe so, but that "rule" (and let's not forget that the zen is not
actually a set of prescriptive rules but rather guidelines for the
informed) is immediately preceded by the most important "rule" of all:
"Beautiful is better than ugly". Nobody will shout at you (well,
hopefully, not on this list they won't) for writing

if my_list != []:
...

in your code, but if they have to incorporate it into their own they
will almost certainly reduce it to

if my_list:
....

It's just idiomatic in Python, the same way that "'Sup?" is idiomatic in
English (or what passes for it nowadays ;-) but grates on those who
aren't used to hearing it.
I'm just starting out with Python with most of my programming in recent
years being in various dialects of Visual Basic (which probably
explains a lot). What attracts me to Python so far is the cool slice
operations, the iterators, the libraries and the convience of
programming in a REPL environment. So far, the ability to use "cat" as
a part-time substitute for True just strikes me as a curiousity - but
maybe that will change with time.
It probably will, but I wouldn't get too hung up on what's definitely a
small point. Enjoy Python the way it is, and the way you are. You and
Python will definitely come to an accommodation (and you will love the
combination of discipline and freedom that it brings to programming
style). Welcome to the language!

regards
Steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC/Ltd http://www.holdenweb.com
Skype: holdenweb http://holdenweb.blogspot.com
Recent Ramblings http://del.icio.us/steve.holden

Oct 26 '06 #35

P: n/a

Skip string ""
Skip list []
Skip tuple ()
Skip dict {}
Skip int 0
Skip float 0.0
Skip complex 0j
Skip set set()
Skip>
SkipAny other value besides the above will compare as "not false".
>And today's question for the novices is: which Python type did Skip
miss from the above list?
Ben bool False

In my rush to reply I missed several others as well. Elucidation left as an
exercise for the reader.

Skip
Oct 26 '06 #36

P: n/a
On Wed, 25 Oct 2006 19:19:59 +0000, John Salerno wrote:
Oh!!! I get it now! I was thinking that

if s

was the same as

if s == True
No. But you know that now :)
because I know sometimes you can write if statements this way (though
it's wordy).
You can, but shouldn't.

But what I didn't realize was that in the cases I was
thinking of, 's' was an expression that evaluated to a boolean value,
not an actual value of some other type!

So I suppose

if (10 5)
Is the same as:

if True

because (10 5) evaluates as True.

would be the same as

if (10 5) == True
Did you mean

if (10 5) == True == True

or

if (10 5) == True == True == True

or even

if (10 5) == True == True == True == True

I hope you see my point now.

because (10 5) does evaluate to "True".
I think it is a good time to remind people of some extremely well-thought
out opposition to the introduction of bools to Python from Laura Creighton:

http://mail.python.org/pipermail/pyt...il/095878.html

She lost the debate, Guido had the final word and Python now has bools.
Take particular note of her description of Python distinguishing between
Something ("cat", 4, [0, 1, 2] etc) and Nothing ("", 0, [] etc).

--
Steven.

Oct 26 '06 #37

P: n/a
In article <ma***************************************@python. org>,
Steve Holden <st***@holdenweb.comwrote:
....
Maybe so, but that "rule" (and let's not forget that the zen is not
actually a set of prescriptive rules but rather guidelines for the
informed) is immediately preceded by the most important "rule" of all:
"Beautiful is better than ugly". Nobody will shout at you (well,
hopefully, not on this list they won't) for writing

if my_list != []:
...

in your code, but if they have to incorporate it into their own they
will almost certainly reduce it to

if my_list:
....

It's just idiomatic in Python, the same way that "'Sup?" is idiomatic in
English (or what passes for it nowadays ;-) but grates on those who
aren't used to hearing it.
It is idiomatic, but not _just_ idiomatic. The former requires
a list object (or a tricky __eq__()), the latter works with a variety
of objects, exhibiting a useful polymorphism.

As for similarities between computer programming languages
and natural languages, I think that breaks down pretty fast.

Part of the problem is something that pinches Python pretty
hard right here, a lack of words that conveniently express
important concepts in the language. A few posts back, Carl
Banks made a distinction between "equaling" and "being", and
if I understood that right, it expresses a fundamental notion
about the meaning of Python's "if", "while" etc. statements.
Unfortunately, though, English conflates existence and identity
in this word ("be"), so it's not going to serve our purposes
very well, and when it comes to words like "if" -- well, we
just have to use what we have.

If there were better words to use with the notion of
"something-ness", I think we would see booleans as a silly
thing of little use to Python programmers. If you can see
"if" and "while" as constructs that respond to something-ness,
you will appreciate idiomatic Python better, because that
arguably is just what it's about.

Donn Cave, do**@u.washington.edu
Oct 26 '06 #38

P: n/a
At Wednesday 25/10/2006 23:29, Paul Rubin wrote:
>Steve Holden <st***@holdenweb.comwrites:
Gabriel Genellina wrote:
iter(())

I get that iter(()) is True (Python 2.3.4).
It's False on 2.4.2 - and perhaps it's what one would expect, but
since this behavior is not documented anywhere, one should not count on it.
--
Gabriel Genellina
Softlab SRL

__________________________________________________
Correo Yahoo!
Espacio para todos tus mensajes, antivirus y antispam ¡gratis!
¡Abrí tu cuenta ya! - http://correo.yahoo.com.ar
Oct 26 '06 #39

P: n/a
Gabriel Genellina <ga******@yahoo.com.arwrites:
At Wednesday 25/10/2006 23:29, Paul Rubin wrote:
Steve Holden <st***@holdenweb.comwrites:
I get that iter(()) is True (Python 2.3.4).

It's False on 2.4.2 - and perhaps it's what one would expect, but
since this behavior is not documented anywhere, one should not count
on it.
Doesn't this fall under "any empty sequence" in the following list of
evaluates-to-false:

<URL:http://docs.python.org/lib/truth.html>

--
\ "If you continue running Windows, your system may become |
`\ unstable." -- Microsoft, Windows 95 BSOD message |
_o__) |
Ben Finney

Oct 26 '06 #40

P: n/a
At Thursday 26/10/2006 19:57, Ben Finney wrote:
>Gabriel Genellina <ga******@yahoo.com.arwrites:
At Wednesday 25/10/2006 23:29, Paul Rubin wrote:
>Steve Holden <st***@holdenweb.comwrites:
>I get that iter(()) is True (Python 2.3.4).
It's False on 2.4.2 - and perhaps it's what one would expect, but
since this behavior is not documented anywhere, one should not count
on it.

Doesn't this fall under "any empty sequence" in the following list of
evaluates-to-false:

<URL:http://docs.python.org/lib/truth.html>
Not exactly, because an iterator is not a sequence.
--
Gabriel Genellina
Softlab SRL

__________________________________________________
Correo Yahoo!
Espacio para todos tus mensajes, antivirus y antispam ¡gratis!
¡Abrí tu cuenta ya! - http://correo.yahoo.com.ar
Oct 26 '06 #41

P: n/a
Ben Finney wrote:
Gabriel Genellina <ga******@yahoo.com.arwrites:

>>At Wednesday 25/10/2006 23:29, Paul Rubin wrote:
>>>Steve Holden <st***@holdenweb.comwrites:
I get that iter(()) is True (Python 2.3.4).
No I didn't - that was Paul Rubin.
>>It's False on 2.4.2 - and perhaps it's what one would expect, but
since this behavior is not documented anywhere, one should not count
on it.


Doesn't this fall under "any empty sequence" in the following list of
evaluates-to-false:

<URL:http://docs.python.org/lib/truth.html>
regards
Steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC/Ltd http://www.holdenweb.com
Skype: holdenweb http://holdenweb.blogspot.com
Recent Ramblings http://del.icio.us/steve.holden

Oct 27 '06 #42

P: n/a
Ben Finney wrote:
Gabriel Genellina <ga******@yahoo.com.arwrites:
At Wednesday 25/10/2006 23:29, Paul Rubin wrote:
>Steve Holden <st***@holdenweb.comwrites:
>I get that iter(()) is True (Python 2.3.4).
It's False on 2.4.2 - and perhaps it's what one would expect, but
since this behavior is not documented anywhere, one should not count
on it.
Good advice, because on 2.5 it's True again.

Doesn't this fall under "any empty sequence" in the following list of
evaluates-to-false:
Nope. An iterator is not a sequence, and it's impossible to determine
whether an iterator is "empty" in general, except by trying to get an
item from it. So even in 2.4.3 some "empty" iterators return True:
>>a = []
bool(x for x in a)
True

The only reasonable advice is to avoid the direct boolean test ("if
a:") altogether if you want to support iterators.

Unfortunately, iterators and lists have a lot of overlapping use, and
it's very common to test for emptiness of lists using "if a:". If one
tries to use an iterator where a list is expected it could lead to a
silent failure.

IMO, this is big time wart in the language. Iterators have no
calculatable truth value; for many other types a truth value doesn't
make sense (for instance: function objects, type objects, modules,
user-defined types that don't bother with __nonzero__). Using such
objects in a boolean context is almost always an error. Objects of
these types should raise exceptions when used as a boolen. numpy
arrays wisely already do this.

(I'll stop short of mentioning that, because neither numpy arrays nor
iterators consider "empty" to be "false", the idea that "empty" is
"false" is very far from self-evident; therefore lists, tuples, dicts,
and sets should also raise exceptions when used as a boolean. I won't
mention that, though.)
Carl Banks

Oct 27 '06 #43

P: n/a
"Carl Banks" <pa************@gmail.comwrites:
An iterator is not a sequence, and it's impossible to determine
whether an iterator is "empty" in general, except by trying to get
an item from it. [...]

IMO, this is big time wart in the language. Iterators have no
calculatable truth value; for many other types a truth value doesn't
make sense (for instance: function objects, type objects, modules,
user-defined types that don't bother with __nonzero__). Using such
objects in a boolean context is almost always an error.
It still seems like a reasonable thing for a programmer to do though,
even if the language doesn't currently support it.

Would it make sense to *define* a truth value for iterators? Or at
least to enable those that *are* able to say "I'm empty" to do so in a
way that boolean contexts can interpret as "false"?

Perhaps allowing (but not requiring) an iterator object to grow a
'len' method is the simplest way.

--
\ "I like my dental hygenist, I think she's very pretty; so when |
`\ I go to have my teeth cleaned, while I'm in the waiting room I |
_o__) eat an entire box of cookies." -- Steven Wright |
Ben Finney

Oct 27 '06 #44

P: n/a
Ben Finney wrote:
Would it make sense to *define* a truth value for iterators? Or at
least to enable those that *are* able to say "I'm empty" to do so in a
way that boolean contexts can interpret as "false"?

Perhaps allowing (but not requiring) an iterator object to grow a
'len' method is the simplest way.
And indeed, they are already allowed to do so.

Python 2.4.1 (#2, Mar 31 2005, 00:05:10)
Type "copyright", "credits" or "license" for more information.

In [1]: len(iter(()))
Out[1]: 0

In [2]: bool(iter(()))
Out[2]: False

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco

Oct 27 '06 #45

P: n/a

Ben Finney wrote:
"Carl Banks" <pa************@gmail.comwrites:
An iterator is not a sequence, and it's impossible to determine
whether an iterator is "empty" in general, except by trying to get
an item from it. [...]

IMO, this is big time wart in the language. Iterators have no
calculatable truth value; for many other types a truth value doesn't
make sense (for instance: function objects, type objects, modules,
user-defined types that don't bother with __nonzero__). Using such
objects in a boolean context is almost always an error.

It still seems like a reasonable thing for a programmer to do though,
even if the language doesn't currently support it.

Would it make sense to *define* a truth value for iterators? Or at
least to enable those that *are* able to say "I'm empty" to do so in a
way that boolean contexts can interpret as "false"?
Again, it's impossible to tell if an iterator is empty in general
except by trying to get an item. You could add a feature to iterators
that fetches an item and stores it, but that would a. be a pain in the
neck for everyone, and b. adversely affect iterators that depend on
outside factors.
Perhaps allowing (but not requiring) an iterator object to grow a
'len' method is the simplest way.
I could live with some iterators defining __len__ or even __nonzero__,
as long as iterators that couldn't determine these things threw an
exception rather than returning a fake value. I'd rather no iterators
did this, though, because having these options makes it likely that
some programmers will write code supporting only "len-able iterators",
thus hindering polymorphism unnecessarily. I'd rather people use
iterators as iterators and not as temporally-challenged lists.

However, it's certainly helpful sometimes to know if an iterator has
any items left (say, to possibly avoid some initialization code). I
don't think this should be a part of iterator protocol, but maybe it'd
be nice if somewhere in the the standard library there was an iterator
type such as this:

class EmptySavvyIterator(object):
noitem = object()
def __init__(self,iterable):
self.iterator = iter(iterable)
self.storage = self.noitem
def __iter__(self):
return self
def next(self):
if self.storage is not self.noitem:
item = self.storage
self.storage = self.noitem
return item
return self.iterator.next()
def empty(self):
if self.storage is not self.noitem:
return False
try:
self.storage = self.iterator.next()
except StopIteration:
return True
return False
# if you must...
def __nonzero__(self):
return not self.empty()
Carl Banks

Oct 27 '06 #46

P: n/a

Robert Kern wrote:
Ben Finney wrote:
Would it make sense to *define* a truth value for iterators? Or at
least to enable those that *are* able to say "I'm empty" to do so in a
way that boolean contexts can interpret as "false"?

Perhaps allowing (but not requiring) an iterator object to grow a
'len' method is the simplest way.

And indeed, they are already allowed to do so.

Python 2.4.1 (#2, Mar 31 2005, 00:05:10)
Type "copyright", "credits" or "license" for more information.

In [1]: len(iter(()))
Out[1]: 0

In [2]: bool(iter(()))
Out[2]: False
And indeed, the built-in iterators have already backed away from this
idea.

Python 2.5c2 (r25c2:51859, Sep 13 2006, 09:50:32)
[GCC 4.1.2 20060814 (prerelease) (Debian 4.1.1-11)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>len(iter(()))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: object of type 'tupleiterator' has no len()
>>bool(iter(()))
True
Carl Banks

Oct 27 '06 #47

P: n/a
On 2006-10-26, Steven D'Aprano <st***@REMOVE.THIS.cybersource.com.auwrote:
On Wed, 25 Oct 2006 19:19:59 +0000, John Salerno wrote:
>Oh!!! I get it now! I was thinking that

if s

was the same as

if s == True

No. But you know that now :)
>because I know sometimes you can write if statements this way (though
it's wordy).

You can, but shouldn't.

>But what I didn't realize was that in the cases I was
thinking of, 's' was an expression that evaluated to a boolean value,
not an actual value of some other type!

So I suppose

if (10 5)

Is the same as:

if True

because (10 5) evaluates as True.

>would be the same as

if (10 5) == True

Did you mean

if (10 5) == True == True

or

if (10 5) == True == True == True

or even

if (10 5) == True == True == True == True

I hope you see my point now.

>because (10 5) does evaluate to "True".

I think it is a good time to remind people of some extremely well-thought
out opposition to the introduction of bools to Python from Laura Creighton:

http://mail.python.org/pipermail/pyt...il/095878.html

She lost the debate, Guido had the final word and Python now has bools.
Take particular note of her description of Python distinguishing between
Something ("cat", 4, [0, 1, 2] etc) and Nothing ("", 0, [] etc).
Yes and IMO that is a less usefull distinction than the distinction
between True and False. When I write code I think in terms of
conditions. In those conditions this has to be treated this way
otherwise it has to be treated an other way. Conditions give
results that are either True or False, not Something or Nothing.
I don't think of 10 5 as Something while 5 < 10 would be
Nothing. So while the paradigma of the language may be the
distinction of Something vs Nothing the programmer will often
enough think in terms of True and False. So IMO it would have
been better if python had made the distinction between True and
False and so made the programmer code the Something/Nothing
disctinction explicitly.

--
Antoon Pardon
Oct 27 '06 #48

P: n/a
On 2006-10-26, Donn Cave <do**@u.washington.eduwrote:
In article <ma***************************************@python. org>,
Steve Holden <st***@holdenweb.comwrote:
...
>Maybe so, but that "rule" (and let's not forget that the zen is not
actually a set of prescriptive rules but rather guidelines for the
informed) is immediately preceded by the most important "rule" of all:
"Beautiful is better than ugly". Nobody will shout at you (well,
hopefully, not on this list they won't) for writing

if my_list != []:
...

in your code, but if they have to incorporate it into their own they
will almost certainly reduce it to

if my_list:
....

It's just idiomatic in Python, the same way that "'Sup?" is idiomatic in
English (or what passes for it nowadays ;-) but grates on those who
aren't used to hearing it.

It is idiomatic, but not _just_ idiomatic. The former requires
a list object (or a tricky __eq__()), the latter works with a variety
of objects, exhibiting a useful polymorphism.
The latter will treat None and False the same as [], () and {},
which in most of my code is not what I want. In most cases
I find testing for an empty sequence (however you do it)
useless, because the loop over the sequence does whatever
I want if it is empty. In cases where I do want to test
for it I usually write:

if len(my_list) 0:

That provides the polymorphism that is usefull to me and
doesn't treat None the same as an empty sequence.
As for similarities between computer programming languages
and natural languages, I think that breaks down pretty fast.

Part of the problem is something that pinches Python pretty
hard right here, a lack of words that conveniently express
important concepts in the language. A few posts back, Carl
Banks made a distinction between "equaling" and "being", and
if I understood that right, it expresses a fundamental notion
about the meaning of Python's "if", "while" etc. statements.
Unfortunately, though, English conflates existence and identity
in this word ("be"), so it's not going to serve our purposes
very well, and when it comes to words like "if" -- well, we
just have to use what we have.

If there were better words to use with the notion of
"something-ness", I think we would see booleans as a silly
thing of little use to Python programmers.
I think you are incorrect. Decisions have to be made and
they are made based on conditions. Conditions are expressed
in terms of True and False not in terms of Nothing or Something.

That is how IMO people think. You can't change that just
because python is implemented with the Nothing vs Something
distinction in mind.
If you can see
"if" and "while" as constructs that respond to something-ness,
you will appreciate idiomatic Python better, because that
arguably is just what it's about.
And how do I express that a number has to be greater than
100 into a Nothing vs Something dichotomy? Declare all
greater numbers as Something and the rest as Nothing?

--
Antoon Pardon
Oct 27 '06 #49

P: n/a
Antoon Pardon wrote:
The latter will treat None and False the same as [], () and {},
which in most of my code is not what I want.
since you never publish any code, what you do in your code is not very
interesting to anyone.

</F>

Oct 27 '06 #50

90 Replies

This discussion thread is closed

Replies have been disabled for this discussion.