1 00:00:00,000 --> 00:00:06,070 2 00:00:06,070 --> 00:00:06,910 PROFESSOR: Hi. 3 00:00:06,910 --> 00:00:09,330 Today I'd like to talk to you about some notable aspects of 4 00:00:09,330 --> 00:00:12,660 Python that you'll encounter in the 6.01 software, as well 5 00:00:12,660 --> 00:00:15,640 as in the general sense when working with Python. 6 00:00:15,640 --> 00:00:19,160 A lot of these little tidbits of Python have some 7 00:00:19,160 --> 00:00:22,050 interesting history associated with them, especially related 8 00:00:22,050 --> 00:00:23,690 to the history of computer science. 9 00:00:23,690 --> 00:00:26,470 And also, I want to indicate some things that tend to mess 10 00:00:26,470 --> 00:00:29,270 up, especially, first time programmers, but also 11 00:00:29,270 --> 00:00:32,020 especially people that are new to Python. 12 00:00:32,020 --> 00:00:34,730 First, I'd like to bring us back to last week. 13 00:00:34,730 --> 00:00:37,140 We were talking about object-oriented programming 14 00:00:37,140 --> 00:00:37,930 and inheritance. 15 00:00:37,930 --> 00:00:40,830 Object-oriented programming is a programming paradigm. 16 00:00:40,830 --> 00:00:43,750 It's in the same category as imperative programming or 17 00:00:43,750 --> 00:00:45,000 functional programming. 18 00:00:45,000 --> 00:00:47,950 And you might say I have a good sense of the fact that in 19 00:00:47,950 --> 00:00:49,860 object-oriented programming, everything is an object. 20 00:00:49,860 --> 00:00:51,780 But I don't really have a good sense of what constitutes 21 00:00:51,780 --> 00:00:54,700 imperative programming or functional programming. 22 00:00:54,700 --> 00:00:56,310 I'm going to focus on functional programming right 23 00:00:56,310 --> 00:00:59,820 now, because it has more of a historic root in the academic 24 00:00:59,820 --> 00:01:01,810 development of computer science. 25 00:01:01,810 --> 00:01:04,819 Functional programming is like object-oriented programming in 26 00:01:04,819 --> 00:01:06,390 that everything is a function. 27 00:01:06,390 --> 00:01:10,080 It refers to the idea that you want to write as much of your 28 00:01:10,080 --> 00:01:12,880 code as possible in a purely functional manner. 29 00:01:12,880 --> 00:01:16,580 And in particular, you're looking for the ability to 30 00:01:16,580 --> 00:01:22,740 avoid things like side-effects or enable many different kinds 31 00:01:22,740 --> 00:01:25,210 of evaluation. 32 00:01:25,210 --> 00:01:27,160 Those kinds of things are not the subject of this course, 33 00:01:27,160 --> 00:01:30,910 but I think they're worth noting to figure out why we're 34 00:01:30,910 --> 00:01:32,830 bothering learning about things like lambdas and list 35 00:01:32,830 --> 00:01:35,760 comprehensions in the first place. 36 00:01:35,760 --> 00:01:38,210 Speaking of which, the first thing we need to talk about 37 00:01:38,210 --> 00:01:40,090 before we even talk about things like lambdas and list 38 00:01:40,090 --> 00:01:43,880 comprehensions, is the concept that in Python, 39 00:01:43,880 --> 00:01:45,440 everything is an object. 40 00:01:45,440 --> 00:01:48,440 But because functions are first-class objects, we can 41 00:01:48,440 --> 00:01:52,030 also treat Python to a large extent like a functional 42 00:01:52,030 --> 00:01:53,310 programming language. 43 00:01:53,310 --> 00:01:55,160 What do I mean when I say functions 44 00:01:55,160 --> 00:01:56,730 are first class objects? 45 00:01:56,730 --> 00:01:59,950 I mean that a function can be the return 46 00:01:59,950 --> 00:02:01,410 value of another function. 47 00:02:01,410 --> 00:02:04,550 I mean that the function can be passed in as an argument to 48 00:02:04,550 --> 00:02:05,400 a function. 49 00:02:05,400 --> 00:02:08,400 And I mean that functions can be assigned variable names and 50 00:02:08,400 --> 00:02:11,170 manipulated the same way that we manipulate any other piece 51 00:02:11,170 --> 00:02:12,730 of data structure. 52 00:02:12,730 --> 00:02:15,820 This is important, because if you want higher order 53 00:02:15,820 --> 00:02:19,840 functions or functions that actually modify or use other 54 00:02:19,840 --> 00:02:23,210 functions as a part of you know, whatever it is they do, 55 00:02:23,210 --> 00:02:25,320 then you need to be able to interact with the function 56 00:02:25,320 --> 00:02:27,930 like it's any other object, in part pass it in 57 00:02:27,930 --> 00:02:29,900 or return it out. 58 00:02:29,900 --> 00:02:31,480 Let's look at an example. 59 00:02:31,480 --> 00:02:37,290 So let's say I start off with a very basic function, right? 60 00:02:37,290 --> 00:02:40,140 If you want to square some sort of value, probably 61 00:02:40,140 --> 00:02:43,340 numeric in this case, then all you have to do is 62 00:02:43,340 --> 00:02:45,180 multiply it by itself. 63 00:02:45,180 --> 00:02:45,860 Pretty simple. 64 00:02:45,860 --> 00:02:47,110 Good place to start. 65 00:02:47,110 --> 00:02:49,220 66 00:02:49,220 --> 00:02:52,160 As a consequence of the idea that functions are first class 67 00:02:52,160 --> 00:02:55,420 objects, I can write a function that takes in a 68 00:02:55,420 --> 00:02:59,650 function as an argument and then develops a return 69 00:02:59,650 --> 00:03:02,980 function that uses the function that I 70 00:03:02,980 --> 00:03:07,690 passed in, on itself. 71 00:03:07,690 --> 00:03:12,890 So any arguments that I would pass to someFunction, I would 72 00:03:12,890 --> 00:03:16,720 pass into someFunction, take the return value of this 73 00:03:16,720 --> 00:03:22,100 function call, and then pass that into someFunction again. 74 00:03:22,100 --> 00:03:25,170 That's what returnFunction does. 75 00:03:25,170 --> 00:03:29,240 And down here, I return returnFunction. 76 00:03:29,240 --> 00:03:31,710 Note that the object type of this 77 00:03:31,710 --> 00:03:34,060 return value is a function. 78 00:03:34,060 --> 00:03:36,950 So once I have returnFunction, I can actually pass it 79 00:03:36,950 --> 00:03:40,400 arguments, have them run through someFunction, not once 80 00:03:40,400 --> 00:03:45,550 but twice, and then get out a value that's of the return 81 00:03:45,550 --> 00:03:47,900 type of someFunction. 82 00:03:47,900 --> 00:03:49,530 Note that I made some assumptions while 83 00:03:49,530 --> 00:03:51,870 writing this function. 84 00:03:51,870 --> 00:03:54,960 First, I've assumed that someFunction returns out the 85 00:03:54,960 --> 00:03:58,530 same number of arguments, and either accept an arbitrary 86 00:03:58,530 --> 00:04:01,880 number of arguments or accepts the same number of arguments 87 00:04:01,880 --> 00:04:04,190 as it puts out. 88 00:04:04,190 --> 00:04:08,610 The other assumption that I've made is that the data type 89 00:04:08,610 --> 00:04:11,310 that someFunction returns is the same as the data types 90 00:04:11,310 --> 00:04:13,140 that someFunction accepts. 91 00:04:13,140 --> 00:04:17,870 Or the things that someFunction does to its 92 00:04:17,870 --> 00:04:20,930 arguments can be done to multiple kinds of arguments. 93 00:04:20,930 --> 00:04:22,430 But that's a whole different argument. 94 00:04:22,430 --> 00:04:27,990 Right now, we're just focusing on the fact that we pass in 95 00:04:27,990 --> 00:04:30,510 some arbitrary number of arguments, call someFunction 96 00:04:30,510 --> 00:04:34,990 on it, call someFunction again on the return value of this, 97 00:04:34,990 --> 00:04:39,520 and return that as something you can do to whatever it is, 98 00:04:39,520 --> 00:04:41,640 someFunction operates on. 99 00:04:41,640 --> 00:04:42,690 OK. 100 00:04:42,690 --> 00:04:44,450 Let's review an example, because I promise it'll be 101 00:04:44,450 --> 00:04:45,700 more clear. 102 00:04:45,700 --> 00:04:47,910 103 00:04:47,910 --> 00:04:49,730 Let's say f is going to be the 104 00:04:49,730 --> 00:04:52,801 composition, a square on itself. 105 00:04:52,801 --> 00:04:59,780 If I do that, I end up with a function that operates on an 106 00:04:59,780 --> 00:05:01,030 arbitrary number of arguments-- 107 00:05:01,030 --> 00:05:04,180 108 00:05:04,180 --> 00:05:05,560 that's not true. 109 00:05:05,560 --> 00:05:09,080 I end up with a copy of square that takes in the same number 110 00:05:09,080 --> 00:05:17,750 of arguments as square called on itself. 111 00:05:17,750 --> 00:05:22,940 So here a square is substituted for someFunction. 112 00:05:22,940 --> 00:05:26,690 Here a square is called on that call of square. 113 00:05:26,690 --> 00:05:28,100 And here is what f is assigned to. 114 00:05:28,100 --> 00:05:31,350 115 00:05:31,350 --> 00:05:35,410 So when I call f of 2, I'm going to 116 00:05:35,410 --> 00:05:38,520 substitute 2 in for args. 117 00:05:38,520 --> 00:05:42,590 I'm going to call square on args. 118 00:05:42,590 --> 00:05:45,180 If I call square on args, I get out 4. 119 00:05:45,180 --> 00:05:50,980 And if I call square on args again, or if I call square of 120 00:05:50,980 --> 00:05:54,420 args where args is defined as the return value of this, then 121 00:05:54,420 --> 00:05:58,120 I'm going to call square on 4, I'll square 4, 122 00:05:58,120 --> 00:05:59,370 and I'll get 16. 123 00:05:59,370 --> 00:06:01,820 124 00:06:01,820 --> 00:06:04,310 Take a second to type it into IDLE, and make it make sense 125 00:06:04,310 --> 00:06:05,130 to yourself. 126 00:06:05,130 --> 00:06:08,200 All of this code should compile. 127 00:06:08,200 --> 00:06:10,010 Mess around with the parameters, if you're having 128 00:06:10,010 --> 00:06:11,360 trouble convincing yourself that it does. 129 00:06:11,360 --> 00:06:16,580 130 00:06:16,580 --> 00:06:16,665 Ok. 131 00:06:16,665 --> 00:06:19,660 Now I think we're ready to talk about lambdas. 132 00:06:19,660 --> 00:06:24,180 If you can pass in functions as arguments or return them as 133 00:06:24,180 --> 00:06:27,640 values or assign them to variable names and just treat 134 00:06:27,640 --> 00:06:30,300 them like any other data type, then you should be able to 135 00:06:30,300 --> 00:06:32,910 treat them as some sort of raw value. 136 00:06:32,910 --> 00:06:36,180 And that's where lambdas come in. 137 00:06:36,180 --> 00:06:39,430 Lambda is a key word in Python that tells you you're about to 138 00:06:39,430 --> 00:06:43,930 use a function that you have not given any sort of name or 139 00:06:43,930 --> 00:06:46,660 defined in any place in your code or environment 140 00:06:46,660 --> 00:06:47,190 beforehand. 141 00:06:47,190 --> 00:06:49,910 You're just going to start talking about something that 142 00:06:49,910 --> 00:06:52,990 you would like to do to a given number of arguments, and 143 00:06:52,990 --> 00:06:55,740 then what you want to return out. 144 00:06:55,740 --> 00:06:59,720 Lambda has roots in lambda calculus which, if you're 145 00:06:59,720 --> 00:07:01,300 familiar with the history of computer science, you've 146 00:07:01,300 --> 00:07:02,850 probably heard of. 147 00:07:02,850 --> 00:07:05,070 Now might be a good time to look up lambda calculus, if 148 00:07:05,070 --> 00:07:08,730 you've never heard it before or possibly Alonzo Church. 149 00:07:08,730 --> 00:07:12,960 But it's still available in code today, which is really 150 00:07:12,960 --> 00:07:17,610 cool, and speaks to the continuing power or at least 151 00:07:17,610 --> 00:07:20,360 recognition of importance of functional programming. 152 00:07:20,360 --> 00:07:23,360 153 00:07:23,360 --> 00:07:26,460 As I said before, the idea with lambda is that you could 154 00:07:26,460 --> 00:07:28,740 write an anonymous function. 155 00:07:28,740 --> 00:07:36,260 Over here, in order to write a function that's squared, I had 156 00:07:36,260 --> 00:07:38,200 to write out a define line. 157 00:07:38,200 --> 00:07:41,690 And because Python uses indentation, because in 158 00:07:41,690 --> 00:07:45,000 Python, indentation carries meaning, I'd have to enter and 159 00:07:45,000 --> 00:07:47,012 return over to a next line-- 160 00:07:47,012 --> 00:07:48,730 I'm actually not sure if that's strictly true. 161 00:07:48,730 --> 00:07:50,620 I think you can do def square x, return 162 00:07:50,620 --> 00:07:54,240 x, but I'm not positive. 163 00:07:54,240 --> 00:07:56,210 I've only seen it written like this. 164 00:07:56,210 --> 00:07:58,810 And I think it's because in the general sense, people try 165 00:07:58,810 --> 00:08:01,060 to respect things like convention and 166 00:08:01,060 --> 00:08:02,310 readability in Python. 167 00:08:02,310 --> 00:08:04,940 168 00:08:04,940 --> 00:08:08,070 If you're using lambda, people already know that you want to 169 00:08:08,070 --> 00:08:09,480 describe a function really quickly. 170 00:08:09,480 --> 00:08:10,920 Or you want to describe function without 171 00:08:10,920 --> 00:08:13,600 assigning it any name. 172 00:08:13,600 --> 00:08:17,270 Therefore, the two most common uses you'll see of lambda is 173 00:08:17,270 --> 00:08:19,430 when you want a really fast function and you don't want to 174 00:08:19,430 --> 00:08:22,500 spend extra time or lines writing out that function. 175 00:08:22,500 --> 00:08:26,340 It's pretty clear what this is going to do. 176 00:08:26,340 --> 00:08:29,020 Or if, in a particular sense, you need 177 00:08:29,020 --> 00:08:30,120 an anonymous function. 178 00:08:30,120 --> 00:08:33,380 You don't want to assign a name or memory space 179 00:08:33,380 --> 00:08:34,630 associated with that function. 180 00:08:34,630 --> 00:08:38,669 181 00:08:38,669 --> 00:08:42,820 Note instead of using square, I can just write out this. 182 00:08:42,820 --> 00:08:45,830 So I saved two lines of code defining square. 183 00:08:45,830 --> 00:08:48,680 And then I don't have to refer back to some earlier part of 184 00:08:48,680 --> 00:08:49,890 the code in order to understand 185 00:08:49,890 --> 00:08:51,570 what this line does. 186 00:08:51,570 --> 00:08:53,520 Pretty cool. 187 00:08:53,520 --> 00:08:54,960 All right. 188 00:08:54,960 --> 00:08:57,650 So there's functions of first class objects. 189 00:08:57,650 --> 00:08:59,350 There's lambda. 190 00:08:59,350 --> 00:09:01,535 Let's talk about how to use lambdas on lists. 191 00:09:01,535 --> 00:09:08,450 192 00:09:08,450 --> 00:09:12,770 In Python, you'll end up doing a lot of list manipulation. 193 00:09:12,770 --> 00:09:19,190 One of the best uses of anonymized functions in any 194 00:09:19,190 --> 00:09:21,480 functional programming language is the ability to 195 00:09:21,480 --> 00:09:23,010 manipulate lists in a line. 196 00:09:23,010 --> 00:09:26,550 197 00:09:26,550 --> 00:09:29,820 If I've defined just a pretty straightforward list right 198 00:09:29,820 --> 00:09:36,700 here, I can use functions like map filter and reduce to-- 199 00:09:36,700 --> 00:09:38,150 in one line-- 200 00:09:38,150 --> 00:09:42,420 take a list, apply a function to every element in that list, 201 00:09:42,420 --> 00:09:48,020 and then return a copy of the result of that list. 202 00:09:48,020 --> 00:09:50,060 I didn't have to write a separate function to do the 203 00:09:50,060 --> 00:09:52,020 list handling. 204 00:09:52,020 --> 00:09:54,405 I didn't have to write a separate function to multiply 205 00:09:54,405 --> 00:09:57,600 the list by two. 206 00:09:57,600 --> 00:09:59,940 And I've communicated what I'm doing effectively to people 207 00:09:59,940 --> 00:10:01,190 that are used to functional programming. 208 00:10:01,190 --> 00:10:04,100 209 00:10:04,100 --> 00:10:08,920 So if you type this line in, you should end up with a 210 00:10:08,920 --> 00:10:12,640 return in interactive mode of every element in this list 211 00:10:12,640 --> 00:10:13,860 multiplied by two. 212 00:10:13,860 --> 00:10:16,210 Now's a good time to try. 213 00:10:16,210 --> 00:10:19,820 Once you've done that, I also recommend looking at the 214 00:10:19,820 --> 00:10:21,750 original copied demolist. 215 00:10:21,750 --> 00:10:23,910 Note that this is unaltered. 216 00:10:23,910 --> 00:10:30,080 Map actually returned a new data structure that represents 217 00:10:30,080 --> 00:10:34,430 performing this function on this list. 218 00:10:34,430 --> 00:10:36,910 This becomes important later when I explain aliasing, but I 219 00:10:36,910 --> 00:10:38,830 will do that in about two minutes. 220 00:10:38,830 --> 00:10:43,930 221 00:10:43,930 --> 00:10:47,460 If we want to get even more elegant, we can use list 222 00:10:47,460 --> 00:10:48,710 comprehensions. 223 00:10:48,710 --> 00:10:50,400 224 00:10:50,400 --> 00:10:51,990 List comprehensions-- 225 00:10:51,990 --> 00:10:54,030 if you ask somebody where list comprehensions are from, 226 00:10:54,030 --> 00:10:56,580 they'll probably say Haskell, because that is the most 227 00:10:56,580 --> 00:11:00,370 popular use of list comprehensions, in terms of 228 00:11:00,370 --> 00:11:03,450 pure lazy functional programming. 229 00:11:03,450 --> 00:11:06,990 But it actually goes back further than that, and is in 230 00:11:06,990 --> 00:11:09,290 Small Talk, and then something from the '60s. 231 00:11:09,290 --> 00:11:10,740 I can't remember the name of it right now. 232 00:11:10,740 --> 00:11:14,620 233 00:11:14,620 --> 00:11:30,630 They're really nice because they borrow a syntactic 234 00:11:30,630 --> 00:11:32,830 approach from mathematicians. 235 00:11:32,830 --> 00:11:35,600 This looks a lot like set notation. 236 00:11:35,600 --> 00:11:39,180 And when you read this, you can probably tell that the 237 00:11:39,180 --> 00:11:44,000 list listComprehension is going to describe a set of 238 00:11:44,000 --> 00:11:46,970 points from 1 to 4. 239 00:11:46,970 --> 00:11:51,910 240 00:11:51,910 --> 00:11:55,980 But you accomplish that in possibly one line of code. 241 00:11:55,980 --> 00:11:59,080 I've written it on three here because I wanted to keep it in 242 00:11:59,080 --> 00:12:00,540 this space. 243 00:12:00,540 --> 00:12:04,790 But it's really concise. 244 00:12:04,790 --> 00:12:07,330 If you type this into IDLE, you should see the kind of 245 00:12:07,330 --> 00:12:10,010 list that it returns, and also what's 246 00:12:10,010 --> 00:12:11,660 listComprehension is now-- 247 00:12:11,660 --> 00:12:12,910 what now constitutes listComprehension. 248 00:12:12,910 --> 00:12:15,320 249 00:12:15,320 --> 00:12:20,690 You can use listComprehensions with functions like map and 250 00:12:20,690 --> 00:12:23,330 filter and reduce. 251 00:12:23,330 --> 00:12:27,810 And, along with the anonymized functions, all of these tools 252 00:12:27,810 --> 00:12:29,890 provide you with a lot of functionality in a very short 253 00:12:29,890 --> 00:12:31,140 amount of space. 254 00:12:31,140 --> 00:12:33,450 255 00:12:33,450 --> 00:12:36,280 It's also good to be able to recognize what's going on when 256 00:12:36,280 --> 00:12:39,530 you see something like this or something like this. 257 00:12:39,530 --> 00:12:41,940 Because you'll probably run into it in, in particular, a 258 00:12:41,940 --> 00:12:46,860 lot with Lisp code, but also in the artificial intelligence 259 00:12:46,860 --> 00:12:48,110 community in particular. 260 00:12:48,110 --> 00:12:52,160 261 00:12:52,160 --> 00:12:52,245 Ok. 262 00:12:52,245 --> 00:12:55,400 We've talked about all that. 263 00:12:55,400 --> 00:12:58,210 Let's take a second to talk about the fact that lists are 264 00:12:58,210 --> 00:13:01,710 actually mutable, and what that means, and what things 265 00:13:01,710 --> 00:13:03,670 you have to be careful about if you're going to be working 266 00:13:03,670 --> 00:13:04,920 with mutable objects. 267 00:13:04,920 --> 00:13:09,500 268 00:13:09,500 --> 00:13:11,640 If you're new to programming, or you're new to Python, 269 00:13:11,640 --> 00:13:13,020 you've probably already worked with some of 270 00:13:13,020 --> 00:13:14,600 these data types, right? 271 00:13:14,600 --> 00:13:18,000 Any numbers, any strings, any tuples, 272 00:13:18,000 --> 00:13:20,610 are going to be immutable. 273 00:13:20,610 --> 00:13:26,920 What that means is if you have a variable and you have a 274 00:13:26,920 --> 00:13:31,210 second variable that has a different assignment line 275 00:13:31,210 --> 00:13:32,370 associated with it-- right? 276 00:13:32,370 --> 00:13:34,640 I haven't assigned g to h here. 277 00:13:34,640 --> 00:13:39,000 I've just signed g to "hello" and h to "hello." 278 00:13:39,000 --> 00:13:43,610 If you look at the space in memory that Python associates 279 00:13:43,610 --> 00:13:48,000 with both objects, they point to the same place. 280 00:13:48,000 --> 00:13:51,140 This is the definition of an immutable object. 281 00:13:51,140 --> 00:13:54,110 When g points to "hello" and h points to "hello," they both 282 00:13:54,110 --> 00:13:55,010 point to the same place. 283 00:13:55,010 --> 00:13:58,040 If x points to 5 and y points to 5, they're both pointing to 284 00:13:58,040 --> 00:13:59,940 the same place. 285 00:13:59,940 --> 00:14:03,120 If you point x at 6, it now points to a 286 00:14:03,120 --> 00:14:04,370 different memory address. 287 00:14:04,370 --> 00:14:08,460 288 00:14:08,460 --> 00:14:10,180 This gets confounded when you're talking 289 00:14:10,180 --> 00:14:11,940 about mutable objects. 290 00:14:11,940 --> 00:14:14,670 The problem with mutable objects is that you select a 291 00:14:14,670 --> 00:14:19,180 memory space to contain the object or memory ID in Python 292 00:14:19,180 --> 00:14:20,500 to contain the object. 293 00:14:20,500 --> 00:14:25,090 And then that object is changed in place. 294 00:14:25,090 --> 00:14:28,460 295 00:14:28,460 --> 00:14:30,290 You can use this to your advantage but it can 296 00:14:30,290 --> 00:14:31,120 also mess with you. 297 00:14:31,120 --> 00:14:32,680 And here's how. 298 00:14:32,680 --> 00:14:37,160 Let's say I assigned a to a small list. 299 00:14:37,160 --> 00:14:41,100 And I also assigned b to a. 300 00:14:41,100 --> 00:14:42,835 b and a now point at the same place. 301 00:14:42,835 --> 00:14:45,660 302 00:14:45,660 --> 00:14:48,540 If I manipulate b, and I'm-- 303 00:14:48,540 --> 00:14:51,309 excuse me-- still working with an immutable object, or excuse 304 00:14:51,309 --> 00:14:58,660 me, if I'm still working with a mutable object, the object 305 00:14:58,660 --> 00:15:01,100 in that memory address has been altered. 306 00:15:01,100 --> 00:15:05,740 And b and a still point to the same place in memory. 307 00:15:05,740 --> 00:15:10,740 So if I look at a, it's going to look like b, which is going 308 00:15:10,740 --> 00:15:12,990 to look like 1, 2, 3, 4 -- 309 00:15:12,990 --> 00:15:16,230 which is not what I assigned a to originally. 310 00:15:16,230 --> 00:15:19,000 Again, can be powerful, but you have to keep it in mind. 311 00:15:19,000 --> 00:15:22,160 And it might start to mess with, in particular, the 6.01 312 00:15:22,160 --> 00:15:26,620 software when you're dealing with state machines. 313 00:15:26,620 --> 00:15:29,220 In order to get around this, you can create a copy of the 314 00:15:29,220 --> 00:15:31,500 list and then modify the copy. 315 00:15:31,500 --> 00:15:34,230 This is actually what map does. 316 00:15:34,230 --> 00:15:36,610 If you want to do it, the easiest way to do it on the 317 00:15:36,610 --> 00:15:40,120 first layer is to specify the index into the 318 00:15:40,120 --> 00:15:42,360 list with no bounce. 319 00:15:42,360 --> 00:15:43,770 It'll copy the whole thing. 320 00:15:43,770 --> 00:15:48,430 There's also a Python library copy or deep copy, if you want 321 00:15:48,430 --> 00:15:50,890 to copy lists of lists of lists of lists of lists. 322 00:15:50,890 --> 00:15:53,420 323 00:15:53,420 --> 00:15:58,690 And just to clarify, you'll note that after you assign c 324 00:15:58,690 --> 00:16:02,780 to a copy of a, c and a occupy different memory places. 325 00:16:02,780 --> 00:16:07,096 So if you modify c, a will retain its original value. 326 00:16:07,096 --> 00:16:11,070 327 00:16:11,070 --> 00:16:12,300 I think that's all the notable things I have 328 00:16:12,300 --> 00:16:13,250 to say about Python. 329 00:16:13,250 --> 00:16:17,200 and gives us enough power to do some really powerful list 330 00:16:17,200 --> 00:16:21,980 manipulation or array manipulation, and covers what 331 00:16:21,980 --> 00:16:23,740 we want to say about functional programming before 332 00:16:23,740 --> 00:16:26,410 we get into the notion of state, which I'll 333 00:16:26,410 --> 00:16:27,660 talk about next time. 334 00:16:27,660 --> 00:16:28,500