1 00:00:00,760 --> 00:00:02,610 - [Narrator] Python makes it really easy 2 00:00:02,610 --> 00:00:04,700 when you have a sequence of values 3 00:00:04,700 --> 00:00:07,510 to obtain a subset of that sequence; 4 00:00:07,510 --> 00:00:10,270 what's known as a slice operation. 5 00:00:10,270 --> 00:00:11,780 In this video and the next, 6 00:00:11,780 --> 00:00:14,810 we're going to talk about various slicing techniques. 7 00:00:14,810 --> 00:00:17,300 Here, we'll focus on slicing techniques 8 00:00:17,300 --> 00:00:19,940 for copying subsets of sequences 9 00:00:19,940 --> 00:00:22,560 and those techniques will work the same way 10 00:00:22,560 --> 00:00:25,240 whether you're talking about lists, 11 00:00:25,240 --> 00:00:26,880 tuples, or strings. 12 00:00:26,880 --> 00:00:28,880 When you take a subset of a list, 13 00:00:28,880 --> 00:00:30,000 you'll get a list, 14 00:00:30,000 --> 00:00:31,720 when you take a subset of a string, 15 00:00:31,720 --> 00:00:32,670 you'll get a string, 16 00:00:32,670 --> 00:00:34,730 and when you take a subset of a tuple, 17 00:00:34,730 --> 00:00:36,140 you'll get a tuple. 18 00:00:36,140 --> 00:00:40,980 Now, you can also use slices to modify mutable sequences, 19 00:00:40,980 --> 00:00:42,150 such as lists, 20 00:00:42,150 --> 00:00:45,620 and we'll demonstrate those techniques in the next video. 21 00:00:45,620 --> 00:00:47,440 So for the purpose of this discussion, 22 00:00:47,440 --> 00:00:50,160 we're going to work with a list called 23 00:00:50,160 --> 00:00:53,320 numbers containing the integers that you see here, 24 00:00:53,320 --> 00:00:56,070 and the data type stored within the list 25 00:00:56,070 --> 00:00:58,600 is somewhat irrelevant for this discussion. 26 00:00:58,600 --> 00:01:00,630 We happen to be using integers, 27 00:01:00,630 --> 00:01:03,220 but of course, you could have a list of anything you want, 28 00:01:03,220 --> 00:01:06,280 and these slicing operations that I'm about to show you 29 00:01:06,280 --> 00:01:09,390 will work for all of those scenarios. 30 00:01:09,390 --> 00:01:11,780 Now, in the list numbers, 31 00:01:11,780 --> 00:01:15,130 let's demonstrate the most basic kind of a slice, 32 00:01:15,130 --> 00:01:16,540 which is where you specify the 33 00:01:16,540 --> 00:01:18,910 starting index of the slice, 34 00:01:18,910 --> 00:01:23,380 and the one past the end index of the slice. 35 00:01:23,380 --> 00:01:24,930 Let's show you what I mean. 36 00:01:24,930 --> 00:01:28,590 So we're going to create a slice expression 37 00:01:28,590 --> 00:01:31,110 where we want to select elements from numbers 38 00:01:31,110 --> 00:01:33,270 starting from index position 2, 39 00:01:33,270 --> 00:01:35,230 so zero, one, two. 40 00:01:35,230 --> 00:01:37,610 We're going to start with the value five, 41 00:01:37,610 --> 00:01:41,480 and in this case, we'd like to go up to but not including 42 00:01:41,480 --> 00:01:43,600 the index six. 43 00:01:43,600 --> 00:01:46,260 So up to but not including the index six, 44 00:01:46,260 --> 00:01:48,660 so we've got three, four, five, 45 00:01:48,660 --> 00:01:50,530 and then this would be the index six. 46 00:01:50,530 --> 00:01:52,840 So we're basically saying that we want 47 00:01:52,840 --> 00:01:56,250 to select these highlighted four elements 48 00:01:56,250 --> 00:01:57,730 from the original list, 49 00:01:57,730 --> 00:02:02,440 and the result of this expression will be a new list 50 00:02:02,440 --> 00:02:05,410 containing copies of the references in the 51 00:02:05,410 --> 00:02:07,970 element positions two through five. 52 00:02:07,970 --> 00:02:10,010 So that's an interesting point, 53 00:02:10,010 --> 00:02:13,360 because that means the new list that I get back 54 00:02:13,360 --> 00:02:16,530 is actually a copy of these references, 55 00:02:16,530 --> 00:02:19,187 and, therefore, both the new sub-list 56 00:02:19,187 --> 00:02:22,550 and the original list refer to the same objects 57 00:02:22,550 --> 00:02:25,310 five, seven, eleven, and thirteen. 58 00:02:25,310 --> 00:02:27,290 This is the result of the expression that 59 00:02:27,290 --> 00:02:28,450 we just typed there, 60 00:02:28,450 --> 00:02:31,860 and, as you can see, again starting from index two, 61 00:02:31,860 --> 00:02:33,680 we go three, four, five, 62 00:02:33,680 --> 00:02:37,370 this is the last element of the subset or the slice, 63 00:02:37,370 --> 00:02:41,780 and then this is the index that we stopped counting at. 64 00:02:41,780 --> 00:02:44,430 So you can see we get the four elements up to 65 00:02:44,430 --> 00:02:47,000 but not including position six 66 00:02:47,000 --> 00:02:50,110 in that subset or that slice. 67 00:02:50,110 --> 00:02:53,380 Now, interestingly, when you're defining slices, 68 00:02:53,380 --> 00:02:56,780 you don't always have to put numbers on both sides 69 00:02:56,780 --> 00:02:58,770 of that colon operation. 70 00:02:58,770 --> 00:03:03,130 So, for example, consider this expression numbers colon six, 71 00:03:03,130 --> 00:03:06,080 in which we imply that we want to 72 00:03:06,080 --> 00:03:08,310 start from the beginning of the list, 73 00:03:08,310 --> 00:03:11,580 and take the subset up to but not including 74 00:03:11,580 --> 00:03:13,380 index position six. 75 00:03:13,380 --> 00:03:18,380 So, implicitly, Python will insert a zero before that colon, 76 00:03:18,570 --> 00:03:20,810 which is the first index in the list 77 00:03:20,810 --> 00:03:24,151 and I will get everything up to but not including 78 00:03:24,151 --> 00:03:26,470 index position six. 79 00:03:26,470 --> 00:03:29,170 So, this expression that we just typed here 80 00:03:29,170 --> 00:03:32,210 is equivalent to saying zero colon six, 81 00:03:32,210 --> 00:03:33,730 so if you know that you always 82 00:03:33,730 --> 00:03:35,160 wanna start from the beginning, 83 00:03:35,160 --> 00:03:38,020 you can leave out the starting index number, 84 00:03:38,020 --> 00:03:41,760 and simply provide a colon and the ending index number, 85 00:03:41,760 --> 00:03:44,750 and you see we get the exact same result. 86 00:03:44,750 --> 00:03:46,400 Now, in a similar fashion, 87 00:03:46,400 --> 00:03:50,530 we can also say go all the way to the end of the list. 88 00:03:50,530 --> 00:03:52,480 So, if we say six colon, 89 00:03:52,480 --> 00:03:55,460 that says start from index position six 90 00:03:55,460 --> 00:03:57,680 and go to the end of the list, 91 00:03:57,680 --> 00:04:01,530 and it will implicitly insert the length of the list 92 00:04:01,530 --> 00:04:03,560 for you in that case. 93 00:04:03,560 --> 00:04:06,870 So, you can see here we get just 17 and 19, 94 00:04:06,870 --> 00:04:10,440 and that last expression is the equivalent 95 00:04:10,440 --> 00:04:12,380 of me going ahead and putting in 96 00:04:12,380 --> 00:04:16,058 the length of the numbers list as the second 97 00:04:16,058 --> 00:04:20,280 index value in that slice expression. 98 00:04:20,280 --> 00:04:21,560 So if I go ahead and do that, 99 00:04:21,560 --> 00:04:25,380 you see we get the exact same results once again. 100 00:04:25,380 --> 00:04:27,910 Now, it turns out that if you ever need to make 101 00:04:27,910 --> 00:04:30,520 a quick copy of a list, 102 00:04:30,520 --> 00:04:33,860 you can use a slicing operation for that 103 00:04:33,860 --> 00:04:38,140 by simply leaving out the indices altogether 104 00:04:38,140 --> 00:04:41,360 and putting a colon inside the square brackets. 105 00:04:41,360 --> 00:04:44,700 In this case, the interpreter is automatically 106 00:04:44,700 --> 00:04:47,530 going to infer zero as the starting index 107 00:04:47,530 --> 00:04:50,270 and the length of the list as the ending index, 108 00:04:50,270 --> 00:04:54,910 and you can see we get a duplicate of the original list. 109 00:04:54,910 --> 00:04:58,140 Now, it's important to note that that is what we call 110 00:04:58,140 --> 00:04:59,820 a shallow copy. 111 00:04:59,820 --> 00:05:03,130 Every slice operation is a shallow copy. 112 00:05:03,130 --> 00:05:06,830 And what that means is we get new data structure objects, 113 00:05:06,830 --> 00:05:10,230 in this case, new lists, from the slice operations, 114 00:05:10,230 --> 00:05:14,210 but we don't get copies of the actual values in memory. 115 00:05:14,210 --> 00:05:18,640 So, there's still only one object with the value two, 116 00:05:18,640 --> 00:05:20,330 one object with the value three, 117 00:05:20,330 --> 00:05:22,670 one object with the value five, et cetera, 118 00:05:22,670 --> 00:05:25,110 and this new list that was just created 119 00:05:25,110 --> 00:05:28,470 refers to the same object containing two 120 00:05:28,470 --> 00:05:29,820 as the original list, 121 00:05:29,820 --> 00:05:32,550 the same object containing three as the original list, 122 00:05:32,550 --> 00:05:35,360 the same object containing five as the original list, 123 00:05:35,360 --> 00:05:36,193 et cetera. 124 00:05:36,193 --> 00:05:38,640 So, it's a shallow copy operation, 125 00:05:38,640 --> 00:05:40,420 and in later lessons, 126 00:05:40,420 --> 00:05:44,230 specifically when we get to the NumPy lesson, 127 00:05:44,230 --> 00:05:46,420 we'll talk about deep copying, 128 00:05:46,420 --> 00:05:50,593 where copies of the actual values get made as well. 129 00:05:51,650 --> 00:05:53,690 Now, as you might expect 130 00:05:53,690 --> 00:05:57,820 from the range function descriptions or discussions 131 00:05:57,820 --> 00:05:59,440 in earlier lessons, 132 00:05:59,440 --> 00:06:04,420 there is also the ability to do slicing with step values, 133 00:06:04,420 --> 00:06:06,500 so you don't always have to select 134 00:06:06,500 --> 00:06:10,230 consecutive elements within your slice. 135 00:06:10,230 --> 00:06:11,390 So, for instance, 136 00:06:11,390 --> 00:06:13,950 if I go ahead and write an expression 137 00:06:13,950 --> 00:06:16,724 like numbers colon colon two, 138 00:06:16,724 --> 00:06:20,900 the first index will be inferred to be zero, 139 00:06:20,900 --> 00:06:23,410 the second index will be inferred to be 140 00:06:23,410 --> 00:06:25,700 the length of the list numbers, 141 00:06:25,700 --> 00:06:28,950 and the third index to the right of the second colon 142 00:06:28,950 --> 00:06:30,140 is the step. 143 00:06:30,140 --> 00:06:32,480 So, what we're saying here is starting from the 144 00:06:32,480 --> 00:06:33,860 beginning of this list, 145 00:06:33,860 --> 00:06:36,120 going all the way through the end of the list, 146 00:06:36,120 --> 00:06:39,610 we want to select every second element. 147 00:06:39,610 --> 00:06:42,240 So, we'll select the element at position zero, 148 00:06:42,240 --> 00:06:45,570 position two, position four, et cetera. 149 00:06:45,570 --> 00:06:50,570 And you can see we get two, five, eleven, and seventeen 150 00:06:50,980 --> 00:06:55,150 as a result of that particular slicing operation. 151 00:06:55,150 --> 00:06:57,770 And, taking that a step further, 152 00:06:57,770 --> 00:06:59,120 no pun intended, 153 00:06:59,120 --> 00:07:01,490 we can count backwards as well. 154 00:07:01,490 --> 00:07:06,490 So, we can say numbers sub colon colon minus one, 155 00:07:07,630 --> 00:07:12,630 and what this says is give me a copy of the entire list 156 00:07:13,400 --> 00:07:14,530 in reverse order. 157 00:07:14,530 --> 00:07:18,330 So, we're basically counting backwards one step at a time. 158 00:07:18,330 --> 00:07:21,550 Now, it's inferring based on the negative step 159 00:07:21,550 --> 00:07:25,480 that we want to start from the end of the list 160 00:07:25,480 --> 00:07:27,150 and work our way backwards, 161 00:07:27,150 --> 00:07:30,080 so you can see that this is a super quick way 162 00:07:30,080 --> 00:07:34,900 to get a reversed list from the original list. 163 00:07:34,900 --> 00:07:37,410 Now, this particular one, 164 00:07:37,410 --> 00:07:41,001 the indices that we're getting as the defaults are 165 00:07:41,001 --> 00:07:45,200 a little bit different from what you might expect. 166 00:07:45,200 --> 00:07:48,370 So, this is actually the equivalent of saying 167 00:07:48,370 --> 00:07:53,080 start from the last element using negative indices 168 00:07:53,080 --> 00:07:55,080 and go backwards 169 00:07:56,378 --> 00:08:00,200 up to but not including nine prior elements. 170 00:08:00,200 --> 00:08:02,420 There's only eight elements in the list. 171 00:08:02,420 --> 00:08:06,070 So this second value, remember, is always up to 172 00:08:06,070 --> 00:08:08,150 but not including that position, 173 00:08:08,150 --> 00:08:10,180 and then we're going to count backwards 174 00:08:10,180 --> 00:08:11,400 one element at a time. 175 00:08:11,400 --> 00:08:13,410 So this is the equivalent, and obviously 176 00:08:13,410 --> 00:08:15,720 that's a little bit hard to figure out, 177 00:08:15,720 --> 00:08:18,380 so this nice, concise notation up above 178 00:08:18,380 --> 00:08:22,500 is the typical way in which you would reverse a list 179 00:08:22,500 --> 00:08:25,760 using a slicing operation. 180 00:08:25,760 --> 00:08:29,050 In the next video, we'll start talking about the slice 181 00:08:29,050 --> 00:08:31,883 operations that can modify a list.