Write Pythonic Code Like a Seasoned Developer Transcripts
Chapter: Generators and Collections
Lecture: Custom iteration and your types
Login or
purchase this course
to watch this video and the rest of the course contents.
0:01
Let's talk about collections, list comprehension,
0:03
generators and generator expressions.
0:06
All of these concepts are extremely central to this idea of Pythonic code,
0:10
many of them are very unique to Python actually.
0:13
The first item we are going to look at is iteration.
0:16
We saw that Python does not have a numerical "for" loop,
0:19
there is no "for(i=0; ;i++)" style loop, you literally work with sequences,
0:24
you iterate over collections and so on.
0:26
There is many built in types that work that way
0:28
such as lists and dictionaries and so on,
0:31
but if we had our own type we defined,
0:33
we might want to be able to iterate over it as well.
0:35
Here is the ShoppingCart class,
0:38
and you can add items to it that you are going to buy later,
0:41
possibly we'd like to create an API such that you can
0:44
iterate over the shopping cart and get the items back.
0:46
Let's have a look over in PyCharm and see how that goes.
0:50
So here is basically the same code and we are defining this thing
0:53
called the CartItem and it's just really a container for a name and a price,
0:57
down on line 15 here, we are going to add three items to our cart,
1:01
a guitar, a cd and an iPhone.
1:04
What if we wanted to loop over our cart? Maybe it works right now,
1:08
let's just try, so if we want to write the code "for item in cart:",
1:12
maybe we'll just print this out, so we'll print,
1:16
let's do the name and we'll do the price here,
1:19
we'll do a little format so we'll say "item.name, item.price".
1:25
And let's do a little header here, so items in your cart.
1:28
You can see that PyCharm is warning us
1:30
we are kind of going down a bad path here, so it's like
1:34
"this is not going to work", but let's go ahead and give it a try,
1:35
just to see what the error is.
1:38
Boom, ShoppingCart object is not iterable.
1:41
OK, so we'd like to write this code but how do we do it?
1:44
the ability to add iteration to a type is based on the Python data model,
1:47
which all the dunder methods comprise.
1:50
So we can come up here and add this particular one,
1:53
we can say "def __iter__" and form this method
1:56
we have to return iterator object, which has a length and next.
2:01
If we just want to loop over the items as they are,
2:03
we can leverage the underlined collection class itself
2:06
and it knows how to create one of these
2:07
so we could just say "self.items.__iter__"
2:12
go back down here, PyCharm is happy, that's a good sign, let's see if it works.
2:16
Boom, "items in your cart: guitar, cd, iPhone". Beautiful.
2:21
What if we wanted to have a little more control than just exposing
2:24
the underline structure, or underline item here,
2:27
what if we wanted to say "sort these and then hand them back"?
2:31
We can come over here and we could say "sorted_items = sorted"
2:36
and we could pass self.items, and we could pass a key selector,
2:41
we could say here is a lambda that given an item is going to return item.price,
2:46
and then we can return sorted_items.__iter__
2:55
now you can see we have out items but sorted,
2:57
not necessarily the same way they were stored before
3:00
and we could even go and say I'd like the negative price here,
3:04
so now we have the most expensive ones first.
3:08
So you might think that this is fairly distasteful here and I don't really like it either,
3:13
we are going to talk more later about generators,
3:16
but if you are familiar with the yield keyword,
3:19
we could write something like this: "for i in sorted items
3:23
yield i", we could write this code as well,
3:26
and this would do basically the same thing,
3:29
it returns the generator rather than list but that's fine.
3:33
So take your pick, we'll talk more about yield later.
3:37
OK, we saw that in order to add iteration to our shopping cart,
3:40
we just need to add a __iter__ method here
3:44
rather than just exposing the underline self.items
3:47
we are actually exposing a sorted version of it as a generator.
3:51
So now we come over here we add some items into it and if you want,
3:55
we can do a "for...in" loop over our cart point out the items as you saw
3:58
and we can grab once we have them, the name and the price and print those out.
4:02
So it's super easy to add custom iterations to your type
4:05
and building on this Python data model with the dunder methods
4:08
sometimes called magic methods is a very Pythonic thing to do.