Alvin C
Alvin C

Reputation: 127

What happens when IF statement is called on a list object? What method is called to determine whether is True or False?

When an IF statement is called on an instance of a list object, is there a magic method that is used to evaluate whether True or False is returned? For example,

a = []
b = [1, 2, 3]

if a == b:  #  <---- __eq__() is called and returns False
    pass

if a:       #  <---- what is called here that returns False?
    pass

Is it: a.__bool__ (a.__nonzero__)? a.__len__?

or something else completely?

Upvotes: 0

Views: 205

Answers (5)

Amadan
Amadan

Reputation: 198418

Experiment time!

class Falsy:
    def __nonzero__(self):
        print("it's __nonzero__")
        return False
    def __len__(self):
        print("it's __len__")
        return 0
    def __bool__(self):
        print("it's __bool__")
        return False
    def __eq__(self, other):
        print("it's __eq__")
        return False

if Falsy():
    pass

# => it's __bool__

You can experiment with removing the methods to confirm which priority they are tested in (__bool__, then __len__, for Python 3).

Upvotes: 2

CryptoFool
CryptoFool

Reputation: 23119

@ymonad gives the best answer in the question's comments, by simply referring to this doc:

https://docs.python.org/3/library/stdtypes.html#truth-value-testing

I don't want credit for this. I just can't handle it when the best answer isn't even an answer. If one can simply point to documentation, that will just about always be the best answer.

...grrrr...hey @ymonad, can I pass you a bounty or something, lol?

Upvotes: 2

AJNeufeld
AJNeufeld

Reputation: 8695

Consulting the C-Python API documentation for PyList ...

https://docs.python.org/3.7/c-api/list.html

... we can see there is no list-specific “as bool” function. The only thing which can return the “truth” value is PyList_Size(PyObject *list), so the answer must be a.__len__() is used.

Disclaimer: At least, for CPython.

Upvotes: 0

Grismar
Grismar

Reputation: 31354

From the documentation https://docs.python.org/2/reference/datamodel.html#object.nonzero:

object.__nonzero__(self)

Called to implement truth value testing and the built-in operation bool(); should return False or True, or their integer equivalents 0 or 1. When this method is not defined, __len__() is called, if it is defined, and the object is considered true if its result is nonzero. If a class defines neither __len__() nor __nonzero__(), all its instances are considered true.

And for Python 3 https://docs.python.org/3.7/reference/datamodel.html#object.nonzero:

object.__bool__(self)

Called to implement truth value testing and the built-in operation bool(); should return False or True. When this method is not defined, __len__() is called, if it is defined, and the object is considered true if its result is nonzero. If a class defines neither __len__() nor __bool__(), all its instances are considered true.

Try:

class MyList(list):
    def __bool__(self):
        return True


print(bool(list([])))
if list([]):
    print('This does not print')


print(bool(MyList([])))
if MyList([]):
    print('This prints')

Upvotes: 0

Edward Aung
Edward Aung

Reputation: 3522

You may want to refer to this answer.

I am not sure what you mean. If I assume you are looking for a Java's .equals() equivalent, I am going to say, there is no such thing in python.

An empty list is always False in python.

Upvotes: -1

Related Questions