Reputation: 379
I'm going through Zed's "Learn Python The Hard Way" and I'm on ex49. I'm quite confused by the following code he gives:
def peek(word_list):
if word_list: # this gives me trouble
word = word_list[0]
return word[0]
else:
return None
The condition of the if
statement is giving me trouble, as commented. I'm not sure what this means as word_list
is an object, not a conditional statement. How can word_list
, just by itself, follow if
?
Upvotes: 5
Views: 1126
Reputation: 17552
Take a look at this docs page for Truth Value Testing in python. You should get clear idea about your situation after reading this. Here is the relevant part for easy access.
5.1. Truth Value Testing
Any object can be tested for truth value, for use in an
if
orwhile
condition or as operand of the Boolean operations below. The following values are considered false:
None
False
- zero of any numeric type, for example,
0
,0.0
,0j
.- any empty sequence, for example,
''
,()
,[]
.- any empty mapping, for example,
{}
.- instances of user-defined classes, if the class defines a
__bool__()
or__len__()
method, when that method returns the integer zero orbool
valueFalse
.All other values are considered true — so objects of many types are always true.
Read the first sentence (bolded) again, and note the bolded parts in the fourth rule. This relates to your question.
So, according to the 4th rule, if your word_list
is empty, the condition evaluates to False
, otherwise it evaluates to True
.
I know you trust in the docs, but here is a code snippet to actually test the truth values for yourself. (I know it is needless to do something like this, but I am always tempted to see things with my own eyes)
def test_truth_value(arg):
# ANY object can be evaluated for truth or false in python
if arg: # or to be more verbose "if arg is True"
print("'{}' is True".format(arg))
else:
print("'{}' is False".format(arg))
class dummy_length_zero():
def __len__(self):
return 0
def __str__(self):
return 'instance of class: "dummy_length_zero"'
class dummy_bool_False():
def __bool__(self):
return False
def __str__(self):
return 'instance of class: "dummy_bool_False"'
obj_dummy_0 = dummy_length_zero()
obj_dummy_false = dummy_bool_False()
args = [None, False, 0, 0.0, 0j, '', (), [], {}, obj_dummy_0, obj_dummy_false]
for arg in args:
test_truth_value(arg)
And lastly, to test that last statement so objects of many types are always true, just remove the implementation of __len__()
or __bool__()
method from dummy_length_zero
or dummy_bool_False
class respectively, and check for truth.
Upvotes: 3
Reputation: 126
In Python, every expression can be evaluated to a boolean value (i.e. either True or False).
The following, basic, expressions evaluate to False
All other expressions evaluate to True.
So, what the if statement does is evaluating the expression that follows the if keyword to either True or False, then act accordingly.
So in your specific example, if word_list
matches any of the above cases it will be considered False, otherwise, it will be considered True.
[#] reference
Upvotes: 2
Reputation: 114230
In python, everything has an implicit boolean value. Putting any object in an if
statement directly is equivalent (but more Pythonic than) doing if bool(word_list):
. None
, empty sequences, empty sets, empty dicts, 0
, False
, 0.0
all evaluate to False
. Most other objects evaluate to True
. That makes if word_list:
the most Pythonic way of ensuring that the list is not None
or empty before accessing the first element. The long way of expressing the same thing would be if word_list is not None and len(word_list) > 0:
.
Upvotes: 2
Reputation: 20336
What is required for an if
block is just something that can be evaluated either to True or to False. A conditional evaluates directly to one of those, but there are other objects that can be converted. To see what any given object is, you can use bool
:
>>> mylist = []
>>> bool(mylist)
False
>>> mylist = [4, 3, 6]
>>> bool(mylist)
True
You see, a list is False if it is empty, but True otherwise. Therefore, the if word_list:
block will be evaluated if word_list
is nonempty. Strings also are False if they are empty, but True otherwise. Same thing with tuples, dictionaries, sets. With numbers, 0 and 0.0 are False, but any other number is True. A fairly common argument to give to indicate to the function to come up with its own value is None
which evaluates to False, so the if not mylist:
block will be executed if mylist
is empty or if mylist
is None
. (It would also be executed if mylist
is 0
, ()
, {}
, etc.; but it's unlikely that mylist
would be given those)
Upvotes: 5
Reputation: 11961
The if
statement applies the built-in bool()
function to the expression which follows. In your case, the code-block inside the if
statement only runs if bool(word_list)
is True
.
Different objects in Python evaluate to either True
or False
in a Boolean context. These objects are considered to be 'Truthy' or 'Falsy'. For example:
In [180]: bool('abc')
Out[180]: True
In [181]: bool('')
Out[181]: False
In [182]: bool([1, 2, 4])
Out[182]: True
In [183]: bool([])
Out[183]: False
In [184]: bool(None)
Out[184]: False
The above are examples of the fact that:
>= 1
are Truthy.>= 1
are Truthy.None
is Falsy.So: if word_list
will evaluate to True
if it is a non-empty list. However, if it is an empty list or None
it will evaluate to False
.
Upvotes: 7
Reputation: 4528
word_list
is a list
and when you use it for an if statement condition you check word_list
is empty or not :
word_list = []
bool(word_list) # False
if word_list :
print "I'm not empty" # would not printed
word_list = ['a']
bool(word_list) # True
if word_list :
print word_list[0] # 'a'
as Mad Physicist said even None elements in a list means that it's not empty:
word_list = [None]
bool(word_list) # True
Upvotes: 5
Reputation: 1246
He is checking if word_list
is empty or not. If a list is empty and it is used in a conditional statement, it is evaluated to False. Otherwise, it is evaluated to True.
word_list = ['some value']
if word_list:
# list is not empty do some stuff
print "I WILL PRINT"
word_list = []
if word_list:
# list is empty
print "I WILL NOT PRINT"
In the above code, only the first snippet will print.
See the following reference: https://docs.python.org/2/library/stdtypes.html#truth-value-testing
Upvotes: 6