Write Pythonic Code Like a Seasoned Developer Transcripts
Chapter: Generators and Collections
Lecture: Custom iteration and your types
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.