1 00:00:07,970 --> 00:00:13,635 Welcome back. What if we really want to control the sort order? 2 00:00:13,635 --> 00:00:15,780 Specifying how to break ties, 3 00:00:15,780 --> 00:00:18,565 on the primary property we're using for sorting? 4 00:00:18,565 --> 00:00:23,720 The answer is that, we take advantages of Python's built-in sort order for tuples. 5 00:00:23,720 --> 00:00:26,690 Take a look at this code, 6 00:00:26,690 --> 00:00:31,500 I have a list containing five tuples. 7 00:00:31,580 --> 00:00:34,710 Each tuple has three items in it. 8 00:00:34,710 --> 00:00:37,920 The first tuple has eight, three, 9 00:00:37,920 --> 00:00:39,870 and two, the second tuple has C, 10 00:00:39,870 --> 00:00:42,820 one, and four, and so on. 11 00:00:43,570 --> 00:00:49,110 On line six, I'm going to sort those tuples. 12 00:00:49,110 --> 00:00:51,790 So we're still going to get a list of five tuples, 13 00:00:51,790 --> 00:00:56,755 and then we're just going to print each of them, with an iteration. 14 00:00:56,755 --> 00:01:00,485 What order do you think, they're going to come out in? 15 00:01:00,485 --> 00:01:02,770 Is it just going to do them in 16 00:01:02,770 --> 00:01:06,130 the original order because it doesn't know how to sort tuples? 17 00:01:06,130 --> 00:01:09,160 Is it going to put all of the As first? 18 00:01:09,160 --> 00:01:11,080 So we'll get this one, 19 00:01:11,080 --> 00:01:12,760 and then this one, 20 00:01:12,760 --> 00:01:14,670 and then the B, 21 00:01:14,670 --> 00:01:16,245 and then the two Cs. 22 00:01:16,245 --> 00:01:18,315 Is it going to do some random order? 23 00:01:18,315 --> 00:01:22,180 What's it going to do? Well let's see. 24 00:01:24,560 --> 00:01:27,870 What it's going to do, is put the As first, 25 00:01:27,870 --> 00:01:29,910 and then, the Bs and then the Cs. 26 00:01:29,910 --> 00:01:32,460 So when you sort tuples, 27 00:01:32,460 --> 00:01:38,270 you're really sorting by the first element in those tuples. But there's more. 28 00:01:38,270 --> 00:01:43,860 We have a built-in tie-breaking mechanism, with tuples sorting. 29 00:01:43,860 --> 00:01:47,054 Here, the first values, 30 00:01:47,054 --> 00:01:50,640 were both A, so it went on to the second value, 31 00:01:50,640 --> 00:01:53,370 and two comes before three. 32 00:01:53,370 --> 00:01:57,620 There was only one B, so there was no tie-breaking that needed to happen. 33 00:01:57,620 --> 00:02:00,980 But between the two Cs, 34 00:02:00,980 --> 00:02:03,935 those are equal, so it goes on to the second element. 35 00:02:03,935 --> 00:02:05,225 If those are equal, 36 00:02:05,225 --> 00:02:08,265 it goes on to compare the third elements. 37 00:02:08,265 --> 00:02:10,500 It would even do fourth and fifth as many, 38 00:02:10,500 --> 00:02:12,620 as you had elements in the tuples. 39 00:02:12,620 --> 00:02:16,295 So, when it compares two tuples, 40 00:02:16,295 --> 00:02:19,100 it first compares their first elements. 41 00:02:19,100 --> 00:02:23,075 If one of them is smaller than that whole tuple is smaller, 42 00:02:23,075 --> 00:02:26,960 but if they're equal, it goes on to compare the second elements of the tuples, 43 00:02:26,960 --> 00:02:29,460 and then the third elements and so on. 44 00:02:29,470 --> 00:02:33,410 So that's going to turn out to be useful for us, 45 00:02:33,410 --> 00:02:36,400 when we try to control a sort order for breaking ties, 46 00:02:36,400 --> 00:02:40,835 even when we're not sorting things that are tuples. 47 00:02:40,835 --> 00:02:45,150 Suppose we had really duplicate items, 48 00:02:45,150 --> 00:02:49,600 so we had another A, three, two. 49 00:02:49,600 --> 00:02:52,890 It's exactly the same as the first element. 50 00:02:53,180 --> 00:02:58,800 In that case, it's just going to put both of them in there, one after the other. 51 00:02:59,840 --> 00:03:02,250 So we've got both of the A, 52 00:03:02,250 --> 00:03:03,870 three, two is showing up. 53 00:03:03,870 --> 00:03:05,650 Is never going to collapse them, 54 00:03:05,650 --> 00:03:08,330 if you have six elements to start with and you sort the list, 55 00:03:08,330 --> 00:03:09,920 you're always going to end up with six elements at 56 00:03:09,920 --> 00:03:13,075 the end even if two of them are identical. 57 00:03:13,075 --> 00:03:16,390 All right, so that's sorting tuples. 58 00:03:16,390 --> 00:03:21,820 We're going to take advantage of the Python sort order for tuples, 59 00:03:21,820 --> 00:03:25,954 in order to be able to specify fine-grained control, 60 00:03:25,954 --> 00:03:28,920 on our sort orders for other things, 61 00:03:28,920 --> 00:03:32,160 using tuples, to create a tie-breaking mechanism. 62 00:03:32,160 --> 00:03:34,710 The way we're going to make this tie-breaking mechanism is that, 63 00:03:34,710 --> 00:03:37,080 we're going to make our key function. 64 00:03:37,080 --> 00:03:40,850 As always take one item as input and it's supposed to 65 00:03:40,850 --> 00:03:45,455 return a property of the item that instead of returning one property of the item, 66 00:03:45,455 --> 00:03:47,345 we're going to return a tuple, 67 00:03:47,345 --> 00:03:50,400 containing two properties of the item. 68 00:03:51,080 --> 00:03:53,475 So here's an example. 69 00:03:53,475 --> 00:03:56,925 We've got a list of fruit names, 70 00:03:56,925 --> 00:04:04,400 and we're going to sort them,and the property that we're going to use to sort them, 71 00:04:04,400 --> 00:04:07,920 is defined by this Lambda expression. 72 00:04:08,180 --> 00:04:12,620 It takes as its input one fruit name, 73 00:04:12,620 --> 00:04:17,194 and it returns as its output, a property, 74 00:04:17,194 --> 00:04:21,875 but in this case it's two properties, as a tuple. 75 00:04:21,875 --> 00:04:25,430 The first one is the length of the fruit name, 76 00:04:25,430 --> 00:04:26,780 how long is the word, 77 00:04:26,780 --> 00:04:29,690 and the other is the fruit name itself. 78 00:04:29,690 --> 00:04:32,780 So this is going to produce for peach, 79 00:04:32,780 --> 00:04:38,620 a tuple five comma peach. 80 00:04:40,550 --> 00:04:46,120 For Kiwi, it's going to produce four comma kiwi. 81 00:04:48,320 --> 00:04:52,270 Remember this idea that the key function is sort of, 82 00:04:52,270 --> 00:04:57,205 producing a post-it note that's associated with the item. 83 00:04:57,205 --> 00:04:59,910 So peach has associated with it, 84 00:04:59,910 --> 00:05:04,495 this tuple, and kiwi has associated with it this tuple. 85 00:05:04,495 --> 00:05:08,530 When sorted it's going to decide what order they should go in, 86 00:05:08,530 --> 00:05:12,295 it's sorting them based on these post-it notes, these tuples. 87 00:05:12,295 --> 00:05:16,270 So, for kiwi is going to go before five peach, 88 00:05:16,270 --> 00:05:18,060 because the tuple ordering says, 89 00:05:18,060 --> 00:05:21,085 "Look at the first element of the tuple first". 90 00:05:21,085 --> 00:05:23,950 However, when it comes along, 91 00:05:23,950 --> 00:05:27,380 and sees four comma pair, 92 00:05:28,020 --> 00:05:30,530 it's going to have a tie, 93 00:05:30,530 --> 00:05:32,615 when it compares four with four, 94 00:05:32,615 --> 00:05:35,395 and it's going to then use alphabetic ordering, 95 00:05:35,395 --> 00:05:39,490 as the secondary sort order to break the ties. 96 00:05:39,490 --> 00:05:42,920 So we'll get as our output. 97 00:05:47,990 --> 00:05:53,025 We get the four-letter fruits first; kiwi and pear, 98 00:05:53,025 --> 00:05:56,790 and then the five letter fruits; apple, mango, 99 00:05:56,790 --> 00:06:00,930 and peach, and those are in alphabetic order. 100 00:06:00,930 --> 00:06:05,415 Apple before mango, m before p, mango before peach. 101 00:06:05,415 --> 00:06:08,560 What if we want to have the long words first? 102 00:06:08,560 --> 00:06:12,009 This is just our standard mechanism, 103 00:06:12,009 --> 00:06:13,380 with the sorted function. 104 00:06:13,380 --> 00:06:16,455 We can add the reverse equals True parameter, 105 00:06:16,455 --> 00:06:18,990 and now we'll get blueberry, 106 00:06:18,990 --> 00:06:21,400 to show up first. 107 00:06:21,410 --> 00:06:25,740 That's all fine, except, 108 00:06:25,740 --> 00:06:30,155 it's completely reversed the sort order from what we had before. 109 00:06:30,155 --> 00:06:31,655 So now we have, 110 00:06:31,655 --> 00:06:33,755 peach before mango before apple. 111 00:06:33,755 --> 00:06:38,300 Those are all the five letter words and we now have them in 112 00:06:38,300 --> 00:06:43,980 reverse alphabetic order in addition to reversing the long words to short words. 113 00:06:44,020 --> 00:06:49,505 What if, we wanted to have longest words first, 114 00:06:49,505 --> 00:06:55,070 but break ties, with alphabetic order rather than reverse alphabetical order? 115 00:06:55,070 --> 00:06:57,805 This starts to get pretty tricky. 116 00:06:57,805 --> 00:07:02,360 One solution that's available to us is a little trick. 117 00:07:02,360 --> 00:07:07,625 Instead of using reverse equals true to reverse our sort order, 118 00:07:07,625 --> 00:07:12,680 which will make it so that we reverse both the primary and the secondary property, 119 00:07:12,680 --> 00:07:15,350 I'm going to try to just reverse the primary property. 120 00:07:15,350 --> 00:07:19,235 There is a trick I can use for numeric properties, 121 00:07:19,235 --> 00:07:20,780 like the length of the fruit name. 122 00:07:20,780 --> 00:07:24,504 If I just make all of them be negative values, 123 00:07:24,504 --> 00:07:27,190 so blueberry is now going to be minus nine, 124 00:07:27,190 --> 00:07:29,530 and kiwi is going to be minus four, 125 00:07:29,530 --> 00:07:32,620 minus nine is less than minus four, 126 00:07:32,620 --> 00:07:36,350 and so I'm going to get the longer ones to come first. 127 00:07:36,350 --> 00:07:39,094 But I haven't reversed everything, 128 00:07:39,094 --> 00:07:43,555 so my secondary sort order is still going to be from lowest to highest, 129 00:07:43,555 --> 00:07:45,375 which will be alphabetic. 130 00:07:45,375 --> 00:07:48,030 So I still got blueberry first, 131 00:07:48,030 --> 00:07:53,475 but I now have apple before mango before peach in alphabetic order. 132 00:07:53,475 --> 00:07:57,035 That trick only works if we have a numeric property. 133 00:07:57,035 --> 00:08:01,610 If you had two alphabetic properties and you wanted to do reverse on one, 134 00:08:01,610 --> 00:08:02,640 and not on the other, 135 00:08:02,640 --> 00:08:06,120 it would be harder and I don't have an easy solution for you. 136 00:08:07,030 --> 00:08:09,365 So summarizing. 137 00:08:09,365 --> 00:08:12,470 If you want to specify a tie-breaking property, 138 00:08:12,470 --> 00:08:15,835 have your key function return a tuple. 139 00:08:15,835 --> 00:08:18,330 Like key functions everywhere, 140 00:08:18,330 --> 00:08:21,350 they always take one item from the sequence as input, 141 00:08:21,350 --> 00:08:23,570 but now it's going to return a tuple, 142 00:08:23,570 --> 00:08:27,949 where the first element of the tuple is the primary property to sort by, 143 00:08:27,949 --> 00:08:30,910 the next element is the secondary property to sort by, 144 00:08:30,910 --> 00:08:34,525 and you could even have more elements in the tuple. 145 00:08:34,525 --> 00:08:37,220 We also saw that if you just want to reverse 146 00:08:37,220 --> 00:08:39,710 order for one of the properties but not the others, 147 00:08:39,710 --> 00:08:41,930 instead of using reverse equals true, 148 00:08:41,930 --> 00:08:49,260 you can make the key function return negative of all the numbers. See you next time.