6

What is process that occurs for a while-loop to evaluate to False on an empty list ?

For instance:

a=[1, 2, 3]
while a:
    a.pop()

Essentially, I want to know which method or attribute of the list object the while-loop is inspecting in order to decide wether to terminate or not.

4
  • Possible duplicate of Empty list is equal to None or not? Commented Oct 18, 2018 at 14:47
  • A better possible duplicate is stackoverflow.com/q/10440792/8344060 Commented Oct 18, 2018 at 14:50
  • 1
    @kvantour. Neither is a good duplicate Commented Oct 18, 2018 at 15:06
  • I agree with @Mad Physicist. I think the question here is much clearer, along with the solution provided. Commented Oct 18, 2018 at 15:12

4 Answers 4

9

Loops and conditionals implicitly use bool on all their conditions. The procedure is documented explicitly in the "Truth Value Testing" section of the docs. For a sequence like a list, this usually ends up being a check of the __len__ method.

bool works like this: first it tries the __bool__ method. If __bool__ is not implemented, it checks if __len__ is nonzero, and if that isn't possible, just returns True.

As with all magic method lookup, Python will only look at the class, never the instance (see Special method lookup). If your question is about how to change the behavior, you will need to subclass. Assigning a single replacement method to an instance dictionary won't work at all.

Sign up to request clarification or add additional context in comments.

3 Comments

Is that true in Python 3+ ? I tried a=[]. Then a.__bool__() and it returns that this method does not exist.
@VanillaSpice. I've added to my answer
Actually, I found this link: docs.python.org/3/library/stdtypes.html#truth, and will add it to your answer to make it more complete.
4

Great question! It's inspecting bool(a), which (usually) calls type(a).__bool__(a).

Python implements certain things using "magic methods". Basically, if you've got a data type defined like so:

class MyExampleDataType:
    def __init__(self, val):
        self.val = val

    def __bool__(self):
        return self.val > 20

Then this code will do what it looks like it'll do:

a = MyExampleDataType(5)
b = MyExampleDataType(30)

if a:
    print("Won't print; 5 < 20")
if b:
    print("Will print; 30 > 20")

For more information, see the Python Documentation: 3.3 Special Method Names.

3 Comments

I tried mylist=[]. Then mylist.__bool__() and it returns that this method does not exist. Is the __bool__ method an actual method of list ?
@VanillaSpinIce It's complicated. Lists are a bad example; there isn't actually a list.__bool__. Read this for in-depth information; basically, Python's making up for the fact that list.__bool__ isn't defined by figuring the information out another way (i.e., using list.__len__). There are hardly any special-cases like that, though (I think the <= comparison operators sometimes use stuff like not > if they're not defined explicitly, but I don't remember).
For backwards compatibility, the truthiness protocol has to keep considering the possibility that a class uses __len__, rather than the newcomer __bool__ (or the Python 2 method __nonzero__ it replaced), to define its truthiness. Since that was the case, there was no compelling reason to define __bool__ and __len__ for the built-in types like list in Python 3.
1

A condition like if my_var is equivalent to if bool(my_var) and this page explains it rather nicely:

Return Value from bool()

The bool() returns:

False if the value is omitted or false True if the value is true

The following values are considered false in Python:

None

False

Zero of any numeric type. For example, 0, 0.0, 0j

Empty sequence. For example, (), [], ''.

Empty mapping. For example, {}

objects of Classes which has bool() or len() method which returns 0 or False

All other values except these values are considered true.

Comments

1

You can check whether a list is empty by using the bool() function. It evaluates to False if the variable doesn't exist or in the case of a list, when it is empty.

In your case you could do this:

a=[1,2,3]

while bool(a) is True:
    a.pop()

Or even easier:

a = [1,2,3]

while len(a) > 0:

    print(a.pop())

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.