# [False,True] and [True,True] --> [True, True]?????

Discussion in 'Python' started by bdb112, Apr 20, 2009.

1. ### bdb112Guest

Is there any obvious reason why
[False,True] and [True,True]
gives [True, True]

Python 2.5.2 (r252:60911, Feb 21 2008, 13:11:45) [MSC v.1310 32 bit
(Intel)]

bdb112, Apr 20, 2009

2. ### Andre EngelsGuest

Re: [False,True] and [True,True] --> [True, True]?????

On Mon, Apr 20, 2009 at 9:03 AM, bdb112 <> wrote:
> Is there any obvious reason why
> [False,True] and [True,True]
> gives [True, True]

Well, whether the reason is obvious, I do not know, but the way and
seems to be implemented is:

X and Y =
* X if the boolean value of X is false
* Y if the boolean value of X is true

In this case, bool([False,True]) = true, so the second element is taken.

--

Andre Engels, Apr 20, 2009

3. ### AggieDan04Guest

Re: and [True,True] --> [True, True]?????

On Apr 20, 2:03 am, bdb112 <> wrote:
> Is there any obvious reason why
> [False,True] and [True,True]
> gives [True, True]
>
> Python 2.5.2 (r252:60911, Feb 21 2008, 13:11:45) [MSC v.1310 32 bit
> (Intel)]

X and Y == (Y if X else X)
X or Y == (X if X else Y)

[False, True] is true, so the and operator returns the second argument.

AggieDan04, Apr 20, 2009
4. ### Gabriel GenellinaGuest

En Mon, 20 Apr 2009 04:03:28 -0300, bdb112 <>
escribió:

> Is there any obvious reason why
> [False,True] and [True,True]
> gives [True, True]

Yes: short-circuit evaluation.
[False,True] and [True,True] is *not* an element-by-element operation,
it's a simple expression involving two objects (two lists).
A and B means: check the boolean value of A; if it's false, return A.
Else, return B.
A non-empty list has a boolean value of true, so the second list is
returned.

If you want an element-wise operation:
A = [False,True]
B = [True,True]
result = [a and b for a,b in zip(A,B)]
--
Gabriel Genellina

Gabriel Genellina, Apr 20, 2009
5. ### bdb112Guest

Re: and [True,True] --> [True, True]?????

THanks Gabriel,
Now I know about the zip function.

Your explanation of Boolean ops on lists was clear.
It leads to some intriguing results:

bool([False])
--> True

I wonder if python 3 changes any of this?

> A and B means: check the boolean value of A; if it's false, return A.
> Else, return B.
> A non-empty list has a boolean value of true, so the second list is
> returned.
>
> If you want an element-wise operation:
> A = [False,True]
> B = [True,True]
> result = [a and b for a,b in zip(A,B)]
> --
> Gabriel Genellina

bdb112, Apr 20, 2009
6. ### Peter OttenGuest

Re: and [True,True] --> [True, True]?????

bdb112 wrote:

> Your explanation of Boolean ops on lists was clear.
> It leads to some intriguing results:
>
> bool([False])
> --> True
>
> I wonder if python 3 changes any of this?

No. Tests like

if items:
...

to verify that items is a non-empty list are a widespread idiom in Python.
They rely on the behaviour you observe.

Peter

Peter Otten, Apr 20, 2009
7. ### Gerhard HäringGuest

Re: and [True,True] --> [True, True]?????

Peter Otten wrote:
> bdb112 wrote:
>
>> Your explanation of Boolean ops on lists was clear.
>> It leads to some intriguing results:
>>
>> bool([False])
>> --> True
>>
>> I wonder if python 3 changes any of this?

>
> No. Tests like
>
> if items:
> ...
>
> to verify that items is a non-empty list are a widespread idiom in Python.
> They rely on the behaviour you observe.

Are they widespread? I haven't noticed, yet.

I prefer to write it explicitly:

if len(lst) > 0:
...

if item is None:
...

etc.

-- Gerhard

Gerhard Häring, Apr 20, 2009
8. ### Chris RebertGuest

Re: and [True,True] --> [True, True]?????

On Mon, Apr 20, 2009 at 1:54 AM, Gerhard HÃ¤ring <> wrote:
> Peter Otten wrote:
>> bdb112 wrote:
>>
>>> Your explanation of Boolean ops on lists was clear.
>>> It leads to some intriguing results:
>>>
>>> bool([False])
>>> --> True
>>>
>>> I wonder if python 3 changes any of this?

>>
>> No. Tests like
>>
>> if items:
>> Â  Â ...
>>
>> to verify that items is a non-empty list are a widespread idiom in Python.
>> They rely on the behaviour you observe.

>
> Are they widespread? I haven't noticed, yet.
>
> I prefer to write it explicitly:
>
> if len(lst) > 0:

Nope, that's not idiomatic. The simpler `if lst:` version is indeed widespread.

> Â  Â ...
>
> if item is None:

That's pretty common and accepted; comparison to None is something of
a special case.

Cheers,
Chris
--
I have a blog:
http://blog.rebertia.com

Chris Rebert, Apr 20, 2009
9. ### Peter OttenGuest

Re: and [True,True] --> [True, True]?????

Gerhard HÃ¤ring wrote:

> Peter Otten wrote:
>> bdb112 wrote:
>>
>>> Your explanation of Boolean ops on lists was clear.
>>> It leads to some intriguing results:
>>>
>>> bool([False])
>>> --> True
>>>
>>> I wonder if python 3 changes any of this?

>>
>> No. Tests like
>>
>> if items:
>> ...
>>
>> to verify that items is a non-empty list are a widespread idiom in
>> Python. They rely on the behaviour you observe.

>
> Are they widespread? I haven't noticed, yet.

That is my impression.

> I prefer to write it explicitly:
>
> if len(lst) > 0:
> ...

matches search expression
ca. 1000 langython "if items:"
216 langython "if len(items) > 0:"

This could of course mean that "people who like 'items' as a list name also
like the 'if items:...' idiom" or "'items' is a popular name for boolean
values" or "the search result is spammed by a gazillion zope versions"...

Peter

Peter Otten, Apr 20, 2009
10. ### Steven D'ApranoGuest

Re: and [True,True] --> [True, True]?????

On Mon, 20 Apr 2009 10:54:40 +0200, Gerhard HÃ¤ring wrote:

> Peter Otten wrote:
>> bdb112 wrote:
>>
>>> Your explanation of Boolean ops on lists was clear. It leads to some
>>> intriguing results:
>>>
>>> bool([False])
>>> --> True
>>>
>>> I wonder if python 3 changes any of this?

>>
>> No. Tests like
>>
>> if items:
>> ...
>>
>> to verify that items is a non-empty list are a widespread idiom in
>> Python. They rely on the behaviour you observe.

>
> Are they widespread? I haven't noticed, yet.
>
> I prefer to write it explicitly:
>
> if len(lst) > 0:

Do you also count the length of a list explicitly?

n = 0
for item in lst:
n += 1
if n > 0:
...

No? Of course you don't. You understand that lists know how to calculate
their own length, and you just ask the list for its length. Great.

Well, lists also know whether or not they are empty, without needing to
concern yourself with the definition of "empty".

if lst:
# not empty
else:
# empty

All Python objects have an understanding of "empty" or "not empty", and
the only time I've seen it cause problems is with iterators, because you
can't tell if an iterator is empty until you actually try to access a
value.

> if item is None:
> ...

That's a completely different test. That's testing whether item is the
specific singleton None. It is very different from testing bool(item).

--
Steven

Steven D'Aprano, Apr 20, 2009
11. ### Peter PearsonGuest

Re: and [True,True] --> [True, True]?????

On 20 Apr 2009 09:26:34 GMT, Steven D'Aprano wrote:
> On Mon, 20 Apr 2009 10:54:40 +0200, Gerhard Häring wrote:

[snip]
>> I prefer to write it explicitly:
>>
>> if len(lst) > 0:

>
> Do you also count the length of a list explicitly?
>
> n = 0
> for item in lst:
> n += 1
> if n > 0:
> ...
>
> No? Of course you don't. You understand that lists know how to calculate
> their own length, and you just ask the list for its length. Great.
>
> Well, lists also know whether or not they are empty, without needing to
> concern yourself with the definition of "empty".
>
> if lst:
> # not empty
> else:
> # empty
>
> All Python objects have an understanding of "empty" or "not empty", and
> the only time I've seen it cause problems is with iterators, because you
> can't tell if an iterator is empty until you actually try to access a
> value.

Like Gerhard, I prefer the construction that explicitly
says, "This is a list, and this is what I'll do if it's not
empty." To me, and I suspect to a great many programmers,
"if x:" does *not* mean "if x is not empty", it means "if
x is (in some sense) True, including the possibility that
x is an object from which a True or False value must be
extracted by means that might not be at all obvious." For
an object lesson in the perils of said extraction, see the
recent thread on [False,True] and [True,True] == [True,True].

People much smarter than me will no doubt rush to point out
that if I were alert, I would know from the context that x
is a list, and if I were thoroughly familiar with Python, I
would know that when x is a list, "if x:" means not empty.
True, but this is all the brain I got, so when I come back
in two months, pathetically disoriented, to peer at this
line of code through my senescent blear, I hope I'll see,
"This, Peter, is a list, and this is what I'll do . . ."

The "not empty" interpretation is a cute shortcut. But
somebody's gotta put up some resistance to cute shortcuts,
or we'll find ourselves back with Perl.

--
To email me, substitute nowhere->spamcop, invalid->net.

Peter Pearson, Apr 20, 2009
12. ### Paul RubinGuest

Re: and [True,True] --> [True, True]?????

Peter Pearson <> writes:
> The "not empty" interpretation is a cute shortcut. But
> somebody's gotta put up some resistance to cute shortcuts,
> or we'll find ourselves back with Perl.

+ QOTW

Paul Rubin, Apr 20, 2009
13. ### Martin v. LöwisGuest

Re: and [True,True] --> [True, True]?????

> Are they widespread? I haven't noticed, yet.
>
> I prefer to write it explicitly:
>
> if len(lst) > 0:

I prefer to test explicitly for the truth value of the
list. I don't want to test whether the length of the list
is greater than 0 (in fact, I don't care about the length
property of the list at all) - I want to know whether the
list is empty (or not empty). The Python syntax for this
test is

if lst:
# not empty

or

if not list:
#empty

The view "let me test for the precise value" leads to
formulations like

if foo is True:
return True
else:
return False

People should have more trust in boolean conversions.

Regards,
Martin

Martin v. Löwis, Apr 20, 2009
14. ### AahzGuest

Re: and [True,True] --> [True, True]?????

In article <>,
=?ISO-8859-1?Q?Gerhard_H=E4ring?= <> wrote:
>
>I prefer to write it explicitly:
>
>if len(lst) > 0:
> ...

At the very least, IMO you should write this as

if len(lst):
...

There's no reason to be explicit about the numeric comparison.
--
Aahz () <*> 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

Aahz, Apr 20, 2009
15. ### Martin v. LöwisGuest

Re: and [True,True] --> [True, True]?????

>> I don't want to test whether the length of the list
>> is greater than 0 [...] - I want to know whether the
>> list is empty (or not empty).

>
> I fail to see the difference between "length greater than 0"
> and "list is not empty". They are, by definition, the same
> thing, aren't they?

Yes, they test the same property, and so would

for x in foo: # foo is empty if it does not have any elements
# not empty
break
else:
# empty

People also write, as a test for empty lists,

if foo == []: # foo is empty when it is equal to the empty list
# empty

if foo != []:
# not empty

Yet another equivalent test would be

try:
foo[0] # foo is empty if it does not have a zeroeth element
except IndexError:
# empty
else:
# not empty

They are *not* the same thing, by definition, as they work
in different ways. They just yield the same result.

There are many equivalent ways to spell this property; some
are more direct than others. I find that referring to the
boolean-ness of a list is the most direct way to test whether
a list is empty - just as testing for the boolean-ness of
an integer is the most direct way to test whether it is 0.

Regards,
Martin

Martin v. Löwis, Apr 20, 2009
16. ### Martin v. LöwisGuest

Re: and [True,True] --> [True, True]?????

>> I prefer to write it explicitly:
>>
>> if len(lst) > 0:
>> ...

>
> At the very least, IMO you should write this as
>
> if len(lst):
> ...
>
> There's no reason to be explicit about the numeric comparison.

I think in the mind-set that dislikes relying on boolean conversion
of lists, relying on boolean conversion of numbers is just as evil.
In this mindset (IIUC), you *have* to have an expression that is
either True or False in a boolean test (if and while).

Regards,
Martin

Martin v. Löwis, Apr 20, 2009
17. ### Gerhard HäringGuest

Re: and [True,True] --> [True, True]?????

Martin v. Löwis wrote:
>> Are they widespread? I haven't noticed, yet.
>>
>> I prefer to write it explicitly:
>>
>> if len(lst) > 0:

>
> I prefer to test explicitly for the truth value of the
> list. I don't want to test whether the length of the list
> is greater than 0 (in fact, I don't care about the length
> property of the list at all) - I want to know whether the
> list is empty (or not empty). The Python syntax for this
> test is
>
> if lst:
> # not empty
>
> or
>
> if not list:
> #empty
> [...]

You're right - as most of the time ;-) This makes a lot of sense to me.

The reason I preferred len(), btw., was only that len() make it clear
that the argument is a sequence.

Maybe I was just too annoyed by lots of Python code I read that looked
like this:

def foo(x, y, z):
if x:
...
else:
...

with poorly named variables where I didn't know what the heck the
variables are (bool, list, instance, ...). I hate it when I have to look
for the actual method calls to figure out what's going in. Better
variable naming and small comments would often help.

-- Gerhard

Gerhard Häring, Apr 20, 2009
18. ### Raymond HettingerGuest

Re: and [True,True] --> [True, True]?????

> > No. Tests like
>
> > if items:
> >    ...

>
> > to verify that items is a non-empty list are a widespread idiom in Python.
> > They rely on the behaviour you observe.

>
> Are they widespread? I haven't noticed, yet.

It's the preferred form (as recommended by PEP 8).

Raymond

Raymond Hettinger, Apr 21, 2009
19. ### Terry ReedyGuest

Re: and [True,True] --> [True, True]?????

Gerhard Häring wrote:
> Martin v. Löwis wrote:
>>> Are they widespread? I haven't noticed, yet.
>>>
>>> I prefer to write it explicitly:
>>>
>>> if len(lst) > 0:

>> I prefer to test explicitly for the truth value of the
>> list. I don't want to test whether the length of the list
>> is greater than 0 (in fact, I don't care about the length
>> property of the list at all) - I want to know whether the
>> list is empty (or not empty). The Python syntax for this
>> test is
>>
>> if lst:
>> # not empty
>>
>> or
>>
>> if not list:
>> #empty
>> [...]

>
> You're right - as most of the time ;-) This makes a lot of sense to me.
>
> The reason I preferred len(), btw., was only that len() make it clear
> that the argument is a sequence.
>
> Maybe I was just too annoyed by lots of Python code I read that looked
> like this:
>
> def foo(x, y, z):
> if x:
> ...
> else:
> ...
>
> with poorly named variables where I didn't know what the heck the
> variables are (bool, list, instance, ...). I hate it when I have to look
> for the actual method calls to figure out what's going in. Better
> variable naming and small comments would often help.

In my view, that is only excusable in throw-away private code or in
languages like early BASIC where only one letter is allowed, and even
then, 'x' should be a number, not a collection.

Terry Reedy, Apr 21, 2009
20. ### Steven D'ApranoGuest

Re: and [True,True] --> [True, True]?????

On Mon, 20 Apr 2009 15:13:15 -0500, Grant Edwards wrote:

> I fail to see the difference between "length greater than 0" and "list
> is not empty". They are, by definition, the same thing, aren't they?

For built-in lists, but not necessarily for arbitrary list-like sequences.

There's also the performance issue. I might have a sequence-like
structure where calling len() takes O(N**2) time, (say, a graph) but
calling __nozero__ might be O(1). Why defeat the class designer's
optimizations?

--
Steven

Steven D'Aprano, Apr 21, 2009