7

In Python, I know the pythonic way to check if a list is empty is

if not a:
    # do things with empty list

To check if a list is not empty then, we would do:

if a:
    # do things with my list

How would we check, simultaneously (as read), if two lists then are not empty?

if a and b:
    # do things with my two lists

The above does not seem to work, and I'm unsure what (a and b) actually means. For a = [2], b = [1,3], (a and b) = [1,3]. What is the and operator actually doing here? If I end up reducing b = [] at some point, (a and b) = [] even though a is not empty.

Edit: My use case goes something like

while (a and b are not empty):
    modify a
    modify b

I would have naively thought that since if a checks if a list is not empty, if a and b would check if neither were empty, which is not the case.

drglove
  • 638
  • 1
  • 6
  • 21
  • 2
    possible duplicate of [Confusion found with and operator](http://stackoverflow.com/questions/24369368/confusion-found-with-and-operator) – vaultah May 27 '15 at 16:22
  • what do you mean when you say "does not .. work"? – Wyrmwood May 27 '15 at 16:23
  • I am having trouble understanding,`if a and b:` will only be True if both are not empty – Padraic Cunningham May 27 '15 at 16:23
  • I'll edit the question to be more concise and check out the duplicate. This one is hard to search for as 'and' is typically not indexed. – drglove May 27 '15 at 16:24
  • `if a and b` does check whether or not both lists are empty. If your seeing things that seem otherwise, your problem is in your loop and not the conditional. – Peter DeGlopper May 27 '15 at 16:34
  • When you say `while (a and b are not empty):`, you you mean "while a is not empty and b is not empty", or "while at least one list is not empty"? e.g. The first will stop the loop when a==[1,2,3] and b==[], but the second will continue. – Kevin May 27 '15 at 16:36

6 Answers6

9

It's working fine. For a = [2] and b = [1, 3], a and b is returning [1, 3] which is truthy, exactly as you would expect, because True and True is True. When you change b to [] it returns [], which is falsy, again exactly as you would expect, because True and False is False. So if a and b does exactly what you want.

What is actually happening is that and is returning the value that decided the truth of the expression. and doesn't always evaluate both sub-expressions; when the first is falsy, the whole expression is falsy and the second doesn't need to be evaluated, and therefore isn't. This is called short-circuiting. or behaves similarly (skipping evaluating the second part if the first part is truthy). Wherever and or or is able to make its decision, it returns that value.

Another way of looking at it: bool(a) and bool(a) == bool(a and b) in Python.

kindall
  • 178,883
  • 35
  • 278
  • 309
2

a and b is correct.

and returns the second argument if the first is true.

Peter DeGlopper
  • 36,326
  • 7
  • 90
  • 83
1

You can do this

if len(a) and len(b):
    #do something
ForceBru
  • 43,482
  • 10
  • 63
  • 98
1

I think what you want is

>>> a, b = list(), list()
>>> while not (a and b):
...    a.append(1)
...    b.append(2)
...
>>> a, b
([1], [2])
>>>
Wyrmwood
  • 3,340
  • 29
  • 33
0

and operator is compare two boolean values

    bool([]) == False

so [] and b always return []; no matter what b is.

Chung-Yen Hung
  • 329
  • 1
  • 6
0

To build on kindall's answer - you could also concatenate the lists before doing the truthiness test:

a = []
b = []
c = [1]
bool(a + b)  # False
bool(a + b + c)  # True

Of course this would come with a performance penalty if you were doing something where that mattered.

cs_stackX
  • 1,407
  • 2
  • 19
  • 27