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.