Rock Solid Python with Python Typing Transcripts
Chapter: Typing in Python
Lecture: More Complex Containers

Login or purchase this course to watch this video and the rest of the course contents.
0:00 Well, what about more complex data structures? I mean, list is interesting, set is kind of like a list,
0:08 but we also have dictionaries, tuples, all sorts of things. We have maybe a list of tuples. These things can combine in interesting ways.
0:17 Now, let's imagine for a minute that the person's number, remember up at the top here they have a name and a number, that their number is distinct.
0:25 It's unique. You can't have more of them. So we've got 42 for Michael, 3 for Sarah, Zoe, 100.
0:30 This is something like, let's say, a user ID for the moment, right, in a database.
0:34 Let's create a dictionary that will allow us to do extremely fast lookups,
0:41 kind of like a database, almost with a primary key, which would be that ID, that number.
0:47 So I'll call it user lookup by ID to be super explicit, no types yet, and wrong symbol. And what we're going to put in here is their number.
0:58 we can use our people to do a dictionary comprehension over here. So we can say p.id.
1:05 Now here's the thing that drives me crazy about comprehensions and generators in Python is you say
1:13 the elements before you say what the type is. So notice I say p. I get nothing. But watch this. but watch this, for pn people, p dot,
1:23 hey, look, there's what I was looking for. Ah, wish those were another order. Anyway, p dot number is the lookup
1:31 and then the value is the person itself. So this dictionary would look like 42 colon 3 colon this,
1:38 right, but we'll just generate it from the data above. Okay, so we got our people and our user lookup here. Let's see how much PyCharm knows already.
1:48 pretty smart about putting these things together. So it does know it's a dictionary, let's say, whatever, but it doesn't know what's contained into it.
1:56 Okay, so that's pretty interesting that it didn't figure that out. But the
2:00 type system knows nothing about this, right? Just like above, it could contain a
2:05 bunch of random things, the keys could be sometimes a number, sometimes a string,
2:10 you don't even know what to put in there. That's a problem, right? But again, like
2:16 this example above, some sometimes this happens in Python when you're matching JSON data,
2:22 but if you're doing a lookup, like given, say an email, I want a user or given their
2:27 ID, I want a user and I've got a bunch of those in there. Well, you want this to be
2:31 a consistent type. Exactly. So let's go and say the type right here, we'll say, this is
2:38 going to be a dictionary. So dict. And just like before, we say of, but instead of having one thing, which is int, right?
2:46 That's the key, this p.number is an int, and PyCharm helpfully tells us that. But what is p itself? The p is a person.
2:56 So we say dict of key value gives us a person, and that gives us all sorts of awesome stuff. So we could try u1 equals user lookup of, let's say,
3:07 and notice right away that PyCharm says, no, no, no, no, no, no. You're trying to index with a key, maybe with a string, maybe like an email,
3:15 but you forgot that this is by ID because we didn't name it well, we just called it user lookup, so what the heck do I use a lookup by, right?
3:23 I gave it a good name, but still this takes ID and this kind of tells you the ID is a number, not a string. Right, so this is gonna throw an exception.
3:36 We could also come over here and say get seven, And this version is going to return none, or whatever default value you put here, we
3:45 could put, you know, default and get the string default back if it doesn't exist. But let's do it like this.
3:51 I will print out you one at the end real quick just to see comes back with none, right?
3:56 Let's see another way which this typing for the dictionary helps us you to let's imagine
4:01 what we were getting back is their name, or their email or some attribute about them, right?
4:08 like dot name. So given their number, we'll get the name back. And that's all we're storing.
4:13 It's not what it is. But imagine so we thought that was the case. And we said, YouTube is
4:18 going to be string equals user lookup dot get. And let's actually get somebody back
4:22 here. Notice again, it says, in the other direction, you think what you're getting back
4:29 here is a string. But what you're actually getting back is a person because the dictionary
4:34 given a key, correct key in this case, gives you back a person or none. So an optional
4:39 person, right? So this is also now again, if we print out you to what we do actually
4:48 get back is the person, Michael here, because the code works, it's just the type system
4:55 is out of place, right? So we'll keep that. Technically, it runs, it's just the types are becoming inconsistent and the editor's letting us know
5:04 that that's the case. Finally, let's say U3 equals user lookup by ID, get three. Now we're not even saying what U3 is, right?
5:13 We've said what U1, we didn't say anything. U2, we tried to say it was a string and it's not, we're getting an error.
5:20 But if I just go down here to U3 and I say dot, check it out, it knows already by type inference, this returns an optional person.
5:30 So all the things that should be happening here are going to be what's available on a person. Now, the final thing we could check here is you for,
5:40 let's say you for as a person. Now, there's no errors here, right? If you look at, there was an error, there was an error,
5:48 but PyCharm is not showing us an error around you for, I think that that is a bug or maybe that's a little harsh limitation of PyCharm
5:59 because what should it be? An optional of person, right? And if you hover over it, PyCharm knows it's an optional person.
6:08 It's a underscore VT pipe none. Okay, great, the value type, but the value type is person, right? So it's given us that back.
6:18 All right, so that's it for this type. We can do similar things for tuples. Like if we had a tuple and it had a number,
6:26 a number, a person, and a string. And you wanted to express this as a tuple of four things, int, int, person, string.
6:40 You can do that by saying this is a typing, not tuple, of int, int, person, str. Okay, perfect. And if this was an int, it'll say, nope,
6:54 you were expecting to have an int int person int and what you gave me is an int int person str, all right?
7:02 So it'll keep those things together, also really nice. This is handy when you have a function, say that returns some kind of well-known tuple, right?
7:11 Maybe it returns two or three different pieces of information all bound together and you can express that as a function
7:18 that will return that, so say def getData, it's gonna return one of them.
7:23 So here if somebody calls this function, and they know they're getting this tuple back,
7:29 I could say t2 equals get data, t2 dot, I'll say, what is the last item? So that would be bracket three dot, it's a string. What about bracket two?
7:44 Person, right? So that gives you a ton of good information. Okay, so this is how we work with more complex containers, right?
7:55 We saw the callable was callable of a list of, say, int int str, right? Similar things here. We say int int person str for this.
8:09 For our data types, we have a key value for dictionaries. Up here we just have the contained type.
8:14 And the main idea is that for many of these, the typing works best if it is a consistent, homogeneous set of things.
8:21 So it's always integers in the list, or always persons in the list, and so on. All right, there it is.


Talk Python's Mastodon Michael Kennedy's Mastodon