WEBVTT 1 00:00:02.200 --> 00:00:05.950 So in the previous video, we started talking about Python dictionaries. 2 00:00:05.950 --> 00:00:09.250 So let's continue on and look at some other features of dictionaries. 3 00:00:09.250 --> 00:00:11.520 Now, on the screen, I've got the code from the last video. 4 00:00:11.520 --> 00:00:15.440 And you saw that we used the .get to retrieve the dictionary. 5 00:00:15.440 --> 00:00:19.630 And we actually use the in key word to actually test to see whether our. 6 00:00:19.630 --> 00:00:23.170 A key that we'll actually type was actually in the dictionary. 7 00:00:23.170 --> 00:00:24.720 So what I'm gonna do is just comment this code out, 8 00:00:24.720 --> 00:00:27.380 cuz I wanted to show you something else that I didn't do in the previous video. 9 00:00:28.790 --> 00:00:29.380 Comment that out. 10 00:00:31.070 --> 00:00:33.920 And what I'm going to do here is just show you an alternative way. 11 00:00:33.920 --> 00:00:38.468 In the previous video, we talked about, showed you how to type description. 12 00:00:38.468 --> 00:00:44.250 Equals fruit.get [INAUDIBLE] and you can see that on the screen there. 13 00:00:44.250 --> 00:00:48.100 But you can also add a default value to return if a key doesn't exist. 14 00:00:48.100 --> 00:00:48.940 So we can do this. 15 00:00:51.320 --> 00:00:57.790 We don't have a [INAUDIBLE] key like so 16 00:00:57.790 --> 00:00:59.300 And we'll do a print description. 17 00:01:02.750 --> 00:01:04.660 And I'll just comment these last two lines out, 18 00:01:04.660 --> 00:01:07.480 cuz they're part of the else that I commented out. 19 00:01:07.480 --> 00:01:10.410 So now if I run that, enter a fruit. 20 00:01:11.840 --> 00:01:14.090 Apple, good for making cider. 21 00:01:14.090 --> 00:01:19.190 Lemon, If I type something like a peach, we don't have a peach. 22 00:01:19.190 --> 00:01:20.790 So you can see what's happening there. 23 00:01:20.790 --> 00:01:21.980 I'll just move this over. 24 00:01:24.170 --> 00:01:24.950 So if what we've typed, 25 00:01:24.950 --> 00:01:30.430 which is stored in the dict_key variable does exist in our dictionary. 26 00:01:30.430 --> 00:01:34.110 It's going to print that out on line 13 This is the default value. 27 00:01:34.110 --> 00:01:37.530 We don't have A plus whatever was typed if it doesn't exist. 28 00:01:37.530 --> 00:01:42.250 So you can see there's two different ways of really achieving the same thing. 29 00:01:42.250 --> 00:01:45.430 Well I guess the question you're probably asking about now is which one one should 30 00:01:45.430 --> 00:01:47.510 you use, and before actually getting into day time and 31 00:01:47.510 --> 00:01:50.640 answering that it's worth pointing out that the second example, 32 00:01:50.640 --> 00:01:53.950 the one that I've now commented out And that was really a little bit contrived 33 00:01:53.950 --> 00:01:56.410 in order to produce the same result as the first one. 34 00:01:56.410 --> 00:01:58.450 So in this particular case, for what we're doing here, 35 00:01:58.450 --> 00:02:01.310 it probably makes sense to do what I've got on the screen now and 36 00:02:01.310 --> 00:02:04.780 just use the default value, because we're not actually doing anything with 37 00:02:04.780 --> 00:02:07.680 that dictionary key that we're typing in, other than printing it out. 38 00:02:07.680 --> 00:02:10.700 But if you're gonna test the return value of description 39 00:02:10.700 --> 00:02:13.880 to see if it contained the default and use that to take some action. 40 00:02:13.880 --> 00:02:16.210 You know if the key doesn't exist in other words and 41 00:02:16.210 --> 00:02:19.230 you probably be better off using the in keyword. 42 00:02:19.230 --> 00:02:21.275 Using the sudden method that is coming to that. 43 00:02:21.275 --> 00:02:24.195 And checking that you key's in the dictionary first, so it really depends on 44 00:02:24.195 --> 00:02:27.075 the functionality you're implementing as to which method you'd use. 45 00:02:27.075 --> 00:02:31.595 The other thing to point out is there actually is a has_key method that used, 46 00:02:31.595 --> 00:02:34.155 that can be used to check if it's in the dictionary, 47 00:02:34.155 --> 00:02:41.501 so you can do something like this. 48 00:02:41.501 --> 00:02:44.025 Fruit.has_key and dict_key for argument's sake. 49 00:02:46.150 --> 00:02:51.020 But has_key is a Python 2 method, and it's not implemented in Python 3, so 50 00:02:51.020 --> 00:02:52.750 it's actually deprecated. 51 00:02:52.750 --> 00:02:53.590 That's why you saw me, 52 00:02:53.590 --> 00:02:58.000 when I was typing has_key, IntelliSense wasn't coming up and using that. 53 00:02:58.000 --> 00:03:01.045 So if you happen to See, has_key. 54 00:03:01.045 --> 00:03:04.913 In any old Python code, you can replace that with this code in here. 55 00:03:04.913 --> 00:03:08.885 So fruit.has_key can be equivalent to dict_key in fruit. 56 00:03:08.885 --> 00:03:11.905 That would be the Python 3 syntax you'd want to use instead. 57 00:03:11.905 --> 00:03:13.355 So I'm just going to comment this out again. 58 00:03:13.355 --> 00:03:18.250 Go back to the original changes that we had before the start of the video. 59 00:03:18.250 --> 00:03:19.040 Like so. 60 00:03:19.040 --> 00:03:19.740 So moving on now. 61 00:03:19.740 --> 00:03:23.290 It's probably not going to surprise you to learn you can also iterate over the keys 62 00:03:23.290 --> 00:03:28.120 of a dictionary in the usual authentic way, so we could do something like this. 63 00:03:28.120 --> 00:03:34.528 And you've used I'd say the for keyword quite a few times, for snack in fruit. 64 00:03:34.528 --> 00:03:40.750 Print fruit snack. 65 00:03:40.750 --> 00:03:41.780 So we could do that. 66 00:03:41.780 --> 00:03:47.244 What we'll do is we'll just comment this whole [INAUDIBLE] we put now. 67 00:03:47.244 --> 00:03:49.800 On the program again, and you can see we've got through, and 68 00:03:49.800 --> 00:03:53.520 it's actually listed out all the values automatically for us. 69 00:03:56.190 --> 00:03:58.960 And we can also access the values as an iterable. 70 00:03:58.960 --> 00:04:02.560 And I'm not sure whether you've noticed, but every time we run this, if we run this 71 00:04:02.560 --> 00:04:07.610 again, noticing the output that's coming through in here, it's changing each time. 72 00:04:07.610 --> 00:04:11.760 The actual order itself is changing each time. 73 00:04:14.640 --> 00:04:17.540 You see that? So the point we're making here. 74 00:04:17.540 --> 00:04:21.820 There's no guarantee that the list is always going to appear in the same 75 00:04:21.820 --> 00:04:22.720 order in a dictionary. 76 00:04:22.720 --> 00:04:23.630 In other words, 77 00:04:23.630 --> 00:04:26.460 just because we enter orange first when we created the dictionary. 78 00:04:26.460 --> 00:04:28.170 In this case we used apple, 79 00:04:28.170 --> 00:04:32.110 doesn't mean it's going to be the first item in the list so to speak. 80 00:04:32.110 --> 00:04:36.050 So the key is hashed and you may find dictionaries refer Refered to as hashes, 81 00:04:36.050 --> 00:04:39.900 and we'll be looking at hash functions later in the course. 82 00:04:39.900 --> 00:04:42.230 But they're basically a one way function. 83 00:04:42.230 --> 00:04:47.460 So, if we use the same hash function on the key apple you always get the same has, 84 00:04:47.460 --> 00:04:50.990 but trying to work out what key was used to produce that has 85 00:04:50.990 --> 00:04:53.090 can take a powerful computer months. 86 00:04:53.090 --> 00:04:57.690 So, hash functions are used for example in cryptography and calculating sums. 87 00:04:57.690 --> 00:04:59.090 You may have done this before. 88 00:04:59.090 --> 00:05:01.900 If you've downloaded files from a reputable source on the internet, 89 00:05:01.900 --> 00:05:05.250 you may have seen MD5 check sum's being referenced. 90 00:05:05.250 --> 00:05:07.820 They're use to check that the file hasn't been tampered with in any way. 91 00:05:07.820 --> 00:05:12.620 In other words, the file that they've created is Is got a unique MD5 checksum. 92 00:05:12.620 --> 00:05:15.470 And they then show you that MD5 checksum. 93 00:05:15.470 --> 00:05:19.720 So when you download on your computer you can actually product that same MD5 94 00:05:19.720 --> 00:05:22.950 checksum by running a command to guarantee that the file hasn't been modified. 95 00:05:22.950 --> 00:05:26.060 A hash would also have a use to store password in the database. 96 00:05:26.060 --> 00:05:28.960 You wouldn't store a password for example as plaintext. 97 00:05:28.960 --> 00:05:32.320 You'd use a hash which could be really useful as well. 98 00:05:32.320 --> 00:05:36.340 So it can be helpful to think of a dictionary as being created with a load of 99 00:05:36.340 --> 00:05:40.610 free slots, and in to those slots our data actually goes, is actually stored. 100 00:05:40.610 --> 00:05:42.440 Now the key is hashed and 101 00:05:42.440 --> 00:05:46.340 the hashed spelling is used to determine which Is used. 102 00:05:46.340 --> 00:05:49.070 Because we're creating the dictionary every time we run the program in 103 00:05:49.070 --> 00:05:49.970 this case. 104 00:05:49.970 --> 00:05:52.800 The slots are allocating different or allocated differently. 105 00:05:52.800 --> 00:05:55.130 So that the algorithms are in different orders. 106 00:05:55.130 --> 00:05:58.210 So Python doesn't randomly move things around though. 107 00:05:58.210 --> 00:06:00.510 As you can see from this next example. 108 00:06:00.510 --> 00:06:02.610 We're going to print this out a number of times. 109 00:06:03.700 --> 00:06:06.750 So let's just leave all that out, just leave the print in there. 110 00:06:06.750 --> 00:06:13.700 So we're doing something like for i in range 10, for snack in food. 111 00:06:13.700 --> 00:06:15.500 You can probably guess what we're doing here. 112 00:06:15.500 --> 00:06:18.310 We're going to run the example ten times now just to see 113 00:06:18.310 --> 00:06:23.270 whether we get a different add value or value From the dictionary, print, snack 114 00:06:24.790 --> 00:06:29.540 plus is, plus fruit snack, and 115 00:06:32.070 --> 00:06:37.310 we're just going to print a separator between each iteration, times 40. 116 00:06:37.310 --> 00:06:42.490 So now, if you run that, You'll notice that in this case, 117 00:06:42.490 --> 00:06:43.560 they're now the same each time. 118 00:06:43.560 --> 00:06:47.150 So each time you're going through the list while we're running it, it's identical for 119 00:06:47.150 --> 00:06:50.950 the 10 times that we've gone through this full loop. 120 00:06:50.950 --> 00:06:53.700 And going through a dictionary, we got the same results. 121 00:06:53.700 --> 00:06:56.260 19 of orange, apple, grape, lime, lemon, 122 00:06:56.260 --> 00:07:00.970 if we run that program again We get lime, lemon, orange, apple, grape this time. 123 00:07:00.970 --> 00:07:01.980 So in other words, 124 00:07:01.980 --> 00:07:08.070 it's the time in the dictionary is created that those start to arbitrarily created, 125 00:07:08.070 --> 00:07:12.170 and the [INAUDIBLE] is sort of putting that in a particular area of memory. 126 00:07:12.170 --> 00:07:17.840 So it's going to be the same for that run, for that program run as you saw Now, 127 00:07:17.840 --> 00:07:21.260 that will only be the case until we modify the dictionary. 128 00:07:21.260 --> 00:07:24.450 So if we ever delete items, anything can happen to the ordering. 129 00:07:24.450 --> 00:07:25.870 So it's not really something you can rely on. 130 00:07:25.870 --> 00:07:30.360 You kind of assume that adding a particular item is going to then make that 131 00:07:30.360 --> 00:07:33.500 item appear in a certain place when you're printing it out or 132 00:07:33.500 --> 00:07:34.980 when you're through that list. 133 00:07:34.980 --> 00:07:37.830 Now there's an ordered dictionary in the collections library which we'll be looking 134 00:07:37.830 --> 00:07:39.600 at later, if you need to do such a thing. 135 00:07:39.600 --> 00:07:42.980 If you do actually want to have a particular order or to use things 136 00:07:42.980 --> 00:07:46.540 a dictionary in an ordered manner, but by default this isn't included. 137 00:07:46.540 --> 00:07:49.500 We'll be looking at that when we cover path and library later in the course. 138 00:07:49.500 --> 00:07:52.190 Keep in mind if you do use that performance would not be as good because 139 00:07:52.190 --> 00:07:56.390 there's more work for Python to actually do to keep things in a orderly fashion. 140 00:07:56.390 --> 00:08:00.940 Now one reason ordering may be important It would be coming to display results for 141 00:08:00.940 --> 00:08:01.930 a human to read. 142 00:08:01.930 --> 00:08:04.780 So in that case rather than loosing performance while you're adding and 143 00:08:04.780 --> 00:08:07.570 deleting from the dictionary it probably could make sense, and 144 00:08:07.570 --> 00:08:10.360 probably would depending on the application to not be concerned with 145 00:08:10.360 --> 00:08:12.670 the ordering until the time comes to display the data. 146 00:08:12.670 --> 00:08:14.670 So in other words you don't try and 147 00:08:14.670 --> 00:08:17.950 do any ordering while the dictionary is being created. 148 00:08:17.950 --> 00:08:21.430 The only time you order it would be at the stage where you want to print it out or 149 00:08:21.430 --> 00:08:23.440 process it in that particular order. 150 00:08:23.440 --> 00:08:26.610 So what we could do at that point is create a list from the dictionary keys, 151 00:08:26.610 --> 00:08:30.220 sort the list, and iterate over the list to display the results. 152 00:08:30.220 --> 00:08:32.290 Now that sounds like a lot of steps, but 153 00:08:32.290 --> 00:08:35.620 this is it's really simple to do as we see here. 154 00:08:35.620 --> 00:08:38.210 So let's go through and see just how easy those steps are. 155 00:08:38.210 --> 00:08:40.610 So we're gonna start with our order keys. 156 00:08:40.610 --> 00:08:45.316 So order [INAUDIBLE] keys equals list [INAUDIBLE] .keys. 157 00:08:46.690 --> 00:08:48.450 Then we're going to sort them. 158 00:08:48.450 --> 00:08:52.005 So we've got the list of keys first from the dictionary then we're going to do 159 00:08:52.005 --> 00:08:58.590 keys.sort and we're going to do [INAUDIBLE] 160 00:08:58.590 --> 00:09:02.610 in ordered keys directly that's with the ordered key in ordered keys. 161 00:09:06.150 --> 00:09:12.130 Print. If as fruit. 162 00:09:12.130 --> 00:09:13.800 If like so. 163 00:09:13.800 --> 00:09:15.500 So if you run that. 164 00:09:16.950 --> 00:09:18.440 We've now got them in the same order. 165 00:09:18.440 --> 00:09:21.720 And every time we run the program we should get the same result as you can 166 00:09:21.720 --> 00:09:24.460 see in the screen there because we are specifically going through that sort 167 00:09:24.460 --> 00:09:25.210 process. 168 00:09:25.210 --> 00:09:29.920 So fruit.keys that returns a list of all the keys just to confirm that. 169 00:09:29.920 --> 00:09:32.100 It's not really the type or kind of list that we're used to. 170 00:09:32.100 --> 00:09:34.250 And as such, it doesn't have a sort command. 171 00:09:34.250 --> 00:09:36.140 So, that's why we had to use the list method. 172 00:09:36.140 --> 00:09:37.970 To create that list. 173 00:09:37.970 --> 00:09:40.270 Because it takes a sequence and produces a list from it. 174 00:09:40.270 --> 00:09:44.240 So, at that point, we've then got a list that we're storing in order_keys. 175 00:09:44.240 --> 00:09:46.010 Then we're using the standard .sort. 176 00:09:46.010 --> 00:09:47.760 Which we've seen before. 177 00:09:47.760 --> 00:09:52.190 And then finally, we're iterating through the list of then ordered keys and 178 00:09:52.190 --> 00:09:54.560 printing out the corresponding entry in the dictionary. 179 00:09:54.560 --> 00:09:56.870 To print it out in alphabetical order. 180 00:09:56.870 --> 00:10:00.120 Now the code's been written on the screen to show what's going on but 181 00:10:00.120 --> 00:10:03.700 you'd normally find that the list is sorted as it's created. 182 00:10:03.700 --> 00:10:06.280 And that can save you one line of code. 183 00:10:06.280 --> 00:10:10.490 So you could have actually done these two lines out. 184 00:10:11.580 --> 00:10:16.310 Just so they're in there for reverence we do ordered underscore keys equals 185 00:10:16.310 --> 00:10:21.160 sorted List(fruit.keys)), 186 00:10:21.160 --> 00:10:26.210 which will achieve the equivalent thing, but with one less line of code. 187 00:10:26.210 --> 00:10:28.630 As you can see, it's still sorting things alphabetically. 188 00:10:28.630 --> 00:10:32.030 If you're not sure why we used the sort method in the first example, But 189 00:10:32.030 --> 00:10:34.550 had to call this sorted function in a second. 190 00:10:34.550 --> 00:10:38.610 Go back and check out section seven, introduction to lists, 191 00:10:38.610 --> 00:10:40.250 where we go through that in detail. 192 00:10:40.250 --> 00:10:44.890 Moving on, finally we can simplify that even further if we don't need the list 193 00:10:44.890 --> 00:10:47.490 object from anything else, other than to iterate [INAUDIBLE] in other words, 194 00:10:47.490 --> 00:10:50.960 if you just Printing something out and you're not going to be using this variable 195 00:10:50.960 --> 00:10:57.079 ordered keys after, you can do that all in one line, so we can, again we'll that out. 196 00:10:58.970 --> 00:11:02.130 Making it something like for f in sorted 197 00:11:04.603 --> 00:11:12.476 fruit.keys print(f + "- " + fruit[f]). 198 00:11:12.476 --> 00:11:16.640 Too many brackets there. 199 00:11:16.640 --> 00:11:20.870 All right, so if we run that, then again we get the same result. 200 00:11:20.870 --> 00:11:23.950 So you can see we become quite concise in Python 201 00:11:23.950 --> 00:11:28.890 really depending in this case whether we're using that variable ordered_keys. 202 00:11:28.890 --> 00:11:29.920 At any other point in the program. 203 00:11:29.920 --> 00:11:34.610 If you want, you can see it became really quite intuitive and 204 00:11:34.610 --> 00:11:36.260 very fast to do what we want it to do. 205 00:11:36.260 --> 00:11:38.990 And really any two lines of code including the printout. 206 00:11:38.990 --> 00:11:42.650 So, just to confirm fruit.keys doesn't return a regular list. 207 00:11:42.650 --> 00:11:46.140 In this case, using the sorter function, it does behave like a sequence. 208 00:11:46.140 --> 00:11:48.790 And as such, we can then pass it to the sorter function. 209 00:11:48.790 --> 00:11:51.410 Because that as input wants a sequence and 210 00:11:51.410 --> 00:11:54.320 that's why that's actually working and that also explains why we had to 211 00:11:54.320 --> 00:11:59.440 create a list from this fruit dot keys output in the first two examples. 212 00:11:59.440 --> 00:12:02.650 And finally, if you wanted to write Over the keys in a dictionary. 213 00:12:02.650 --> 00:12:05.210 You don't actually need to use the keys with it. 214 00:12:05.210 --> 00:12:08.700 We're using it here because we want to sort the keys first before we process it 215 00:12:08.700 --> 00:12:09.690 any further. 216 00:12:09.690 --> 00:12:10.880 So, if you're not sorting. 217 00:12:10.880 --> 00:12:14.170 Basically, that line there will be done with. 218 00:12:15.790 --> 00:12:18.530 Our for f in fruit. 219 00:12:18.530 --> 00:12:19.520 We can assign apple. 220 00:12:21.310 --> 00:12:24.090 And you can now that's now not sorted in alphabetical order 221 00:12:24.090 --> 00:12:25.630 because we've removed the sorted command. 222 00:12:25.630 --> 00:12:28.230 So that's, again, why we've added that. 223 00:12:28.230 --> 00:12:31.170 The .keys need it if we're gonna be using the sort order function 224 00:12:31.170 --> 00:12:33.710 we need to make sure that we use .keys to return a sequence so 225 00:12:33.710 --> 00:12:35.550 that can then sort it into the correct order. 226 00:12:35.550 --> 00:12:39.520 Now, we looked at the keys method to obtain a list of the dictionary keys as 227 00:12:39.520 --> 00:12:41.740 you can see there on screen. 228 00:12:41.740 --> 00:12:45.290 You can probably guess that we can get a list of values by using, you guessed it. 229 00:12:45.290 --> 00:12:46.130 The values command. 230 00:12:46.130 --> 00:12:49.990 So we can do something like, again. 231 00:12:51.280 --> 00:12:54.681 For val in fruit.values. 232 00:12:54.681 --> 00:12:56.759 That's right. 233 00:12:56.759 --> 00:12:58.700 Print val, we can run that. 234 00:13:00.540 --> 00:13:02.360 And that's instead giving us the key. 235 00:13:02.360 --> 00:13:06.040 It gives us the value for each of the items in the But 236 00:13:06.040 --> 00:13:08.840 it's less efficient than using the keys to produce the same results. 237 00:13:08.840 --> 00:13:12.060 So keep that in mind that it's better to use the keys wherever possible. 238 00:13:12.060 --> 00:13:15.660 And use these references in here when you're out putting display It's not really 239 00:13:15.660 --> 00:13:17.740 as optimized and thus it's less efficient. 240 00:13:17.740 --> 00:13:18.630 Sufficient. 241 00:13:18.630 --> 00:13:19.750 And started doing something like this. 242 00:13:19.750 --> 00:13:21.160 So we'll just put a separator in there. 243 00:13:25.170 --> 00:13:27.700 Four key in fruit is gonna be much more efficient. 244 00:13:27.700 --> 00:13:30.200 So print fruit key like so. 245 00:13:30.200 --> 00:13:31.440 Running that. 246 00:13:31.440 --> 00:13:35.510 The second method there is far more efficient. 247 00:13:35.510 --> 00:13:40.240 And we've looked at keys and values now, both of those return list like objects. 248 00:13:40.240 --> 00:13:41.150 And just as a recap. 249 00:13:46.450 --> 00:13:51.172 print, fruit.keys and print fruit. 250 00:13:51.172 --> 00:13:58.530 [INAUDIBLE] I can see that 251 00:13:58.530 --> 00:14:05.090 both return list like objects, so the keys method is returning a dict keys object. 252 00:14:05.090 --> 00:14:09.720 And values returns a dict values object, and both of these are what's called a View 253 00:14:09.720 --> 00:14:14.040 objects and if the underlying dictionary changes, then they will as well. 254 00:14:14.040 --> 00:14:17.700 So the best way to see how that works is to show some example code. 255 00:14:17.700 --> 00:14:21.940 We can assign the dictionary keys to a variable to monitor dictionary and 256 00:14:21.940 --> 00:14:23.560 check what happens to the variable. 257 00:14:23.560 --> 00:14:25.210 So coming back here, we'll close down the run window. 258 00:14:25.210 --> 00:14:29.710 And we'll create a variable, fruit underscore keys. 259 00:14:29.710 --> 00:14:30.870 It's fruit dot keys. 260 00:14:34.170 --> 00:14:38.190 Now print fruit dot keys or fruit underscore keys, I should say. 261 00:14:38.190 --> 00:14:39.810 And I'll just delete these others now. 262 00:14:41.080 --> 00:14:45.114 So we've got that, and then we could do a fruit, [SOUND] 263 00:14:45.114 --> 00:14:49.246 tomato, [SOUND] 264 00:14:49.246 --> 00:14:56.036 equals not nice with ice cream, print 265 00:14:56.036 --> 00:15:02.780 Fruit bring that we haven't updated Fruit keys. 266 00:15:02.780 --> 00:15:06.550 We haven't made another call now to the keys method. 267 00:15:06.550 --> 00:15:07.420 Run that. 268 00:15:07.420 --> 00:15:08.920 I'm going to end this video here. 269 00:15:08.920 --> 00:15:11.920 In the next video we're going to continue our discussion of dictionaries