3.7.0 (v3.7.0:1bf9cc5093, Jun 26 2018, 23:26:24) [Clang 6.0 (clang-600.0.57)] Python Type "help", "copyright", "credits" or "license" for more information. # More on lists l1 = [1, 2, 3] l1[0] 1 l2 = l1 l2 [1, 2, 3] id(l1) 4522708488 id(l2) 4522708488 # lists are mutable # mutable == changeable # we can change the contents of the list without changing its # memory address help(list.append) Help on method_descriptor: append(self, object, /) Append object to the end of the list. l1.append('cat') l1 [1, 2, 3, 'cat'] id(l1) 4522708488 l2 [1, 2, 3, 'cat'] id(l2) 4522708488 # since l1 and l2 both have the same memory address, when we add to one # list, we add to the other # the method list.append does not create a new list with a new # memory address, it just 'edits' the list in place # It keeps the same memory address # List methods that mutate (change) lists help(list.append) Help on method_descriptor: append(self, object, /) Append object to the end of the list. help(list.insert) Help on method_descriptor: insert(self, index, object, /) Insert object before index. L = [1, 2, 3, 4] L.insert(2, 5) L [1, 2, 5, 3, 4] id(L) 4522578120 L.insert(len(L), 5) L [1, 2, 5, 3, 4, 5] id(L) 4522578120 K = L K.insert(len(L), 7) K [1, 2, 5, 3, 4, 5, 7] L [1, 2, 5, 3, 4, 5, 7] id(K) 4522578120 id(L) 4522578120 help(list.sort) Help on method_descriptor: sort(self, /, *, key=None, reverse=False) Stable sort *IN PLACE*. L.sort() L [1, 2, 3, 4, 5, 5, 7] # also sorts in place - memory address doesn't change K [1, 2, 3, 4, 5, 5, 7] # These three methods all change the list without changing the # memory address # Are there ways to make new lists with new memory addresses? # Yes list1 = ['september', 'october', 'november'] list1 ['september', 'october', 'november'] list2 = list1 + ['december'] list2 ['september', 'october', 'november', 'december'] list1 ['september', 'october', 'november'] id(list1) 4522580680 id(list2) 4522578376 # different memory addresses # make a full copy of a list at a different memory address: list3 = list2[:] list3 ['september', 'october', 'november', 'december'] list2 ['september', 'october', 'november', 'december'] list3.append('january') list3 ['september', 'october', 'november', 'december', 'january'] list2 ['september', 'october', 'november', 'december'] id(list3) 4522870088 id(list2) 4522578376 # summary: # operations that create new lists (with different memory addresses): # 1. constructing a new list [.,.,..] # 2. slicing [:], [1:2] # 3. concatenation: list2 = list1 + [...] # operations that modify/mutate an exisiting list (no new list or mem # address): # 1. list.append # 2. list.insert # 3. list.remove # 4. list.sort # 5. most other list methods (but not all) empty_list = [] empty_list [] empty_list2 = [] id(empty_list) 4522580552 id(empty_list2) 4520617736 empty_list1.append('hello') Traceback (most recent call last): Python Shell, prompt 82, line 1 builtins.NameError: name 'empty_list1' is not defined empty_list.append('hello') empty_list ['hello'] empty_list2 [] # Strings are *not* mutable s = 'time' # how can we change s to refer to the string 'lime'? # can we change one letter in s in place? s[0] = 'l' Traceback (most recent call last): Python Shell, prompt 90, line 1 builtins.TypeError: 'str' object does not support item assignment # strings are not mutable # we can index them s[0], but we cannot change the characters in place # and have s change autoatically # since lists are mutable, we can do this l1 [1, 2, 3, 'cat'] l1[0] = 'hi' l1 ['hi', 2, 3, 'cat'] id(l1) 4522708488 l1[2] = 777 l1 ['hi', 2, 777, 'cat'] id(l1) 4522708488 s 'time' id(s) 4519967072 s = 'l' + s[1:] s 'lime' id(s) 4522538968 s[0] = 'l' Traceback (most recent call last): Python Shell, prompt 107, line 1 builtins.TypeError: 'str' object does not support item assignment # Do not forget: Strings are *not* mutable help(range) Help on class range in module builtins: class range(object) | range(stop) -> range object | range(start, stop[, step]) -> range object | | Return an object that produces a sequence of integers from start (inclusive) | to stop (exclusive) by step. range(i, j) produces i, i+1, i+2, ..., j-1. | start defaults to 0, and stop is omitted! range(4) produces 0, 1, 2, 3. | These are exactly the valid indices for a list of 4 elements. | When step is given, it specifies the increment (or decrement). | | Methods defined here: | | __bool__(self, /) | self != 0 | | __contains__(self, key, /) | Return key in self. | | __eq__(self, value, /) | Return self==value. | | __ge__(self, value, /) | Return self>=value. | | __getattribute__(self, name, /) | Return getattr(self, name). | | __getitem__(self, key, /) | Return self[key]. | | __gt__(self, value, /) | Return self>value. | | __hash__(self, /) | Return hash(self). | | __iter__(self, /) | Implement iter(self). | | __le__(self, value, /) | Return self<=value. | | __len__(self, /) | Return len(self). | | __lt__(self, value, /) | Return self integer -- return number of occurrences of value | | index(...) | rangeobject.index(value, [start, [stop]]) -> integer -- return index of value. | Raise ValueError if the value is not present. | | ---------------------------------------------------------------------- | Static methods defined here: | | __new__(*args, **kwargs) from builtins.type | Create and return a new object. See help(type) for accurate signature. | | ---------------------------------------------------------------------- | Data descriptors defined here: | | start | | step | | stop range(0, 10) range(0, 10) for i in range(0, 10): print(i) 0 1 2 3 4 5 6 7 8 9 for i in range(10): print(i) 0 1 2 3 4 5 6 7 8 9 for i in range(5, 10): print(i) 5 6 7 8 9 for i in range(3, 10, 2): print(i) 3 5 7 9 L [1, 2, 3, 4, 5, 5, 7] len(L) 7 for i in range(len(L)): print(i) 0 1 2 3 4 5 6 for i in range(len(L)): print(L[i]) 1 2 3 4 5 5 7 L [1, 2, 3, 4, 5, 5, 7] # Worksheet a = [1, 0] a = a + [8] a [1, 0, 8] a = [1, 0] id(a) 4522561736 a = a + [8] id(a) 4522562120 a = [a[0], a[1], 8] a [1, 0, 8] id(a) 4522564744 a.append(8) id(a) 4522564744 a.insert(len(a), 8) a [1, 0, 8, 8, 8] len(a) 5 id(a) 4522564744 # 2. a = [1,0,8] b = a.sort() a == [1, 0, 8] False a [0, 1, 8] a == [0, 1, 8] True b == [1, 0, 8] False b == [0, 1, 8] False b # b = a.sort() sets the value of a.sort() to b # but a.sort() only changes a and returns nothing # so b has the value None # a.sort() has a return value of None, which gets assigned to b a = [0, 1, 2] b = a b[2] = 100 a == [0, 1, 2] and b == [0, 1, 100] False a == [0, 1, 2] False b == [0, 1, 100] True id(b) 4522562312 id(a) 4522562312 for i range(1, 24, 2): print('na') Traceback (most recent call last): Python Shell, prompt 158, line 1 Syntax Error: invalid syntax: , line 1, pos 11 for i in range(1, 24, 2): print('na') na na na na na na na na na na na na