Write Pythonic Code Like a Seasoned Developer Transcripts
Chapter: Foundational Concepts
Lecture: Truthiness and boolean statements
0:01 Now that we've got more or less obvious PEP 8 items out of the way,
0:04 let's talk about a handful of what I consider foundational items.
0:08 They don't fit neatly into some classification like loops,
0:11 or classes or something like that,
0:14 but they are really important so I put them at the beginning.
0:17 The first thing I want to talk about is what I am calling truthiness,
0:21 the ability to take some kind of symbol or object in Python
0:25 and test it and have it tell us whether or not
0:27 it should evaluate to be True or False.
0:30 So just to remind you in case you don't remember
0:32 all the nuances of truthiness in Python,
0:35 there is a list of things that are defined to be False,
0:38 and then if it's not in this list, if it doesn't match one of the items on the list,
0:41 it's considered to be True.
0:43 So obviously, the keyword "False" is False,
0:46 empty sequences or collections, lists, dictionaries, sets, strings,
0:51 those types of things, those are all considered to be False
0:54 even though they are objects which are pointing to real live instances.
0:58 The numerical values zero integer and zero float are False,
1:02 "None", that is the thing that represents pointing to nothing, is False
1:07 and unlike other languages like say C
1:09 where the null is actually defined to just be a sort of type def back to the zero,
1:15 "None" is not zero but it's still considered to be False.
1:18 And if you have a custom type you can actually define its truthiness by
1:22 in Python 3 defining a dunder bool, or Python 2 dunder non-zero.
1:28 All right, if you are not on that list, then whatever you are testing against is True.
1:32 Now let's just review, that's not Pythonic code per se,
1:35 so let's see how this leads us to Pythonic behavior
1:38 around testing for True and False.
1:41 All right, here I have a real basic method I call print truthiness,
1:44 and let's just test it here, I can say print the truthiness of True
1:54 and we could also test False I suppose,
1:57 so if I run this, no surprise, True is True, False is False
2:01 and you can see we are using this ternary statement here,
2:04 "TRUE if" expression, "else FALSE".
2:07 Now we are not saying if expression == True,
2:10 we are using the implicit truthiness of whatever it is that we are passing,
2:15 here it's the True and False values, but it could also be a sequence,
2:19 it could be some other kind of expression, all right.
2:23 So the recommendation for Pythonic tests on True/False like this
2:28 is to do something along these lines,
2:30 it's to actually use the truthiness inherent in the object itself,
2:34 so you would say something like if I had a val, let's just say it's 7,
2:39 I would say "if val" and down here I would do something,
2:43 I wouldn't say "if value == True", or "if value is not equal to zero",
2:47 I would just use the implicit truthiness that here is a number,
2:51 if it's non-zero, which in theory I was testing for, it's True, otherwise it's False.
2:56 So let's see this for sequences, so if I have some sequence,
3:00 let's make a list, it could be a dictionary or whatever,
3:03 we could print the truthiness of empty list
3:07 and we could have our sequence here,
3:09 and you can see an empty list is False,
3:11 but now if I add something and I run it again,
3:15 and I test for the list with one item,
3:18 then you can see, now it's coming out to be True.
3:20 You can see we can put in here numbers like zero,
3:24 we can put in 11, or even -11,
3:30 and zero of course is False, the others are True.
3:33 Now we can call this function print_truthiness on "None" as well,
3:37 maybe leave a little comment here, we'll say "for none",
3:40 if we pass None, it's going to evaluate to be False,
3:43 this is not the best way if you are explicitly expecting None to test for it
3:47 we'll talk about that as a separate item,
3:49 finally we can define a class called a class or whatever you want to call it
3:53 and maybe it's going to have some kind of internal collection,
3:57 we'd like to surface that so we could use the instance of this class itself
4:01 in a sort of truthiness way, so down here we'll give it some data like a list here,
4:09 we'll give it the ability to add an item to its set
4:11 and then we'll go over here and since it's Python 3,
4:14 we are going to define dunder bool
4:16 and here for bool we can define one of these ternary statements,
4:20 we can say "return True if self.data" and just leverage
4:24 the truthiness of data itself, "else return False".
4:27 And then once we do this, we can come down here and say "a = AClass()",
4:31 we can print and of course if we run it empty, we would expect it to be False,
4:37 and there it is, it's False,
4:39 now if we add and item to it and we print it again, now it evaluates to True.
4:46 So the Pythonic expectation here or the Pythonic style is
4:50 when you are testing objects, leverage their implicit truthiness,
4:54 now we'll write something like "this is True if
4:56 the length of data is greater than zero."
4:59 Now, we don't want to write that,
5:00 we just want to say "if data", it has an implicit truthiness
5:04 and we are going to leverage that.
5:06 So here you can see we've got basically the same code,
5:09 True if the expression evaluates to True, via its implicit truthiness,
5:13 else we'll state False, we've got empty collection and it evaluates to False.
5:17 We add something to the collection and it evaluates to True,
5:19 however notice we can't actually test the data equal to True
5:24 so we can't say print me the truthiness of "data == True" because that's False,
5:28 these are not the same things,
5:29 you are basically comparing a list to a singleton True value,
5:34 a boolean which never is going to be equal,
5:36 so it's always going to say False,
5:38 but we can leverage the truthiness of data and it will come back as True.
5:42 Finally, if we are going to create a custom type
5:44 that is itself imbued with truthiness,
5:46 we give it a dunder bool method
5:48 and then we just return True or False, depending on how we want it to behave.
5:52 You can see below our empty version is False, our non-empty version is True.