This blog post mainly explains the advanced features of list s, including aliasing, mutability, and cloning.These three attributes require special attention when assigning values.This note and code comes from MIT's public session, Lesson 5. <Introduction to Computer Science and Programming in Python>.
aliasing
For simple data types, such as int, after assigning b = a, b only gets the address of A.If the value of b is modified, the address of b changes at the same time.
a = 1 b = a print('id(a) is ',id(a)) print('id(b) is ',id(b)) print('a is',a) print('b is',b)
id(a) is 1865706560 id(b) is 1865706560 a is 1 b is 1
b = 3 print('id(a) is ',id(a)) print('id(b) is ',id(b)) print('a is',a) print('b is',b)
id(a) is 1865706560 id(b) is 1865706624 a is 1 b is 3
For complex data structures, such as list s, after assigning a value with hot = warm, the hot is an aliasing of the warm, and changing the members of the hot will change the warm.The example explains the side effects of append().You can see from the example below that warm and hot have the same memory address.
warm = ['red', 'yellow', 'orange'] hot = warm hot.append('pink') print('id(warm) is',id(warm)) print('id(hot) is',id(hot)) print('warm is',warm) print('hot is',hot)
id(warm) is 2533068903048 id(hot) is 2533068903048 warm is ['red', 'yellow', 'orange', 'pink'] hot is ['red', 'yellow', 'orange', 'pink']
cloning
If we need to create a new list and get a copy, it's also called cloning.Statement chill = cool[:] is required.It is important to note that at this time the copy is a shallow copy, which only copies one layer.If the members of the list are int, it doesn't matter if str is a simple data structure.However, if the members of a list are complex data structures, such as a list, a shallow copy only copies the outer list to get a new address, and the address of the member list does not change.If you need a complete copy, you need a deep copy.
Examples are as follows
cool = ['blue', 'green', 'grey'] chill = cool[:] chill.append('black') print(chill) print(cool)
['blue', 'green', 'grey', 'black'] ['blue', 'green', 'grey']
Shallow and deep copies
import copy list1 = [[1,2],[2,3],[3,4],[4,5]] list2 = list1.copy() print('after copy') print('id list1 is ', id(list1)) print('id list2 is ', id(list2)) print('id list1[0] is ', id(list1[0])) print('id list2[0] is ', id(list2[0])) list1[0][0] = 0 print('modify list1[0][0]') print('list1 = ', list1) print('list2 = ',list2) print('id list1[0] is ', id(list1[0])) print('id list2[0] is ', id(list2[0])) list1[0] = [0,1] print('modify list1[0]') print('list1 = ', list1) print('list2 = ', list2) print('id list1[0] is ', id(list1[0])) print('id list2[0] is ', id(list2[0])) list2 = copy.deepcopy(list1) list1[0][0]= 1 print('after deepcopy') print('modify list1[0][0]') print('id list1 is ', id(list1)) print('id list2 is ', id(list2)) print('id list1[0] is ', id(list1[0])) print('id list2[0] is ', id(list2[0])) print('list1 = ', list1) print('list2 = ', list2)
after copy,Shallow copy, list1 and list2 The addresses are different, but they share a piece of memory space. list1[0]and list2[0]The address is the same id list1 is 1839475337736 id list2 is 1839475372680 id list1[0] is 1839475372168 id list2[0] is 1839475372168 modify list1[0][0] list1 = [[0, 2], [2, 3], [3, 4], [4, 5]] list2 = [[0, 2], [2, 3], [3, 4], [4, 5]] id list1[0] is 1839475372168 id list2[0] is 1839475372168 modify list1[0] list1 = [[0, 1], [2, 3], [3, 4], [4, 5]] list2 = [[0, 2], [2, 3], [3, 4], [4, 5]] id list1[0] is 1839463834568 id list2[0] is 1839475372168 after deepcopy,Deep copy, list1 and list2 Addresses are different and point to different memory spaces, and no modifications will affect each other. modify list1[0][0] id list1 is 1839475337736 id list2 is 1839475375048 id list1[0] is 1839463834568 id list2[0] is 1839475336584 list1 = [[1, 1], [2, 3], [3, 4], [4, 5]] list2 = [[0, 1], [2, 3], [3, 4], [4, 5]]
Use of sort() and sorted
The.sort() method and sorted are used when sorting data of type list is required.
.sort() has no return value and changes the contents of the list.
sorted() must assign the result to another list variable and will not change the input list variable.
######################### ## EXAMPLE: sorting with/without mutation ######################### warm = ['red', 'yellow', 'orange'] sortedwarm = warm.sort() print(warm) print(sortedwarm) cool = ['grey', 'green', 'blue'] sortedcool = sorted(cool) print(cool) print(sortedcool)
['orange', 'red', 'yellow'] None ['grey', 'green', 'blue'] ['blue', 'green', 'grey']
The case where a member of a list is a list
When a list member is a list, the member list only saves one address throughout the list.
Appnd is used, passing in the address of a member list.Changing the value of a member list affects the value of the overall list.
######################### ## EXAMPLE: lists of lists of lists... ######################### warm = ['yellow', 'orange'] hot = ['red'] brightcolors = [warm] brightcolors.append(hot) print(brightcolors) hot.append('pink') print(hot) print(brightcolors)
[['yellow', 'orange'], ['red']] ['red', 'pink'] [['yellow', 'orange'], ['red', 'pink']]
Modify list during looping
############################### ## EXAMPLE: mutating a list while iterating over it ############################### def remove_dups(L1, L2): for e in L1: if e in L2: L1.remove(e) def remove_dups_new(L1, L2): L1_copy = L1[:] for e in L1_copy: if e in L2: L1.remove(e) L1 = [1, 2, 3, 4] L2 = [1, 2, 5, 6] remove_dups(L1, L2) print(L1, L2) L1 = [1, 2, 3, 4] L2 = [1, 2, 5, 6] remove_dups_new(L1, L2) print(L1, L2)
[2, 3, 4] [1, 2, 5, 6] [3, 4] [1, 2, 5, 6]