MIT6.0001 笔记,LECTURE 5:Tuples, List (aliasing, mutability, cloning详解)

这一篇博客主要来解释list的高级特性,主要包括aliasing,mutability,和cloning。这三个特性在赋值时需要特别注意。本篇笔记和代码都来自于MIT的公开课,第五课。《Introduction to Computer Science and Programming in Python》

aliasing

对于简单的数据类型,比如int,使用 b = a 赋值之后,b只是得到了a的地址。如果修改b的值,则b的地址同时改变。

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

对于复杂的数据结构,比如list,使用 hot = warm赋值之后,hot 是warm的一个aliasing,改变其中的hot的成员将会改变warm。示例解释了append()的副作用。从下面的例子中可以看到warm和hot拥有同样的内存地址。

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

如果我们需要新建一个list,然后得到一份拷贝,也叫cloning。需要使用语句chill = cool[:]。需要注意的是,此时的拷贝是一种浅拷贝,浅拷贝只会拷贝一层。如果list的成员是int,str这些简单数据结构是没关系的。但是,如果一个list的成员是复杂数据结构,比如list,浅拷贝只会拷贝外层的list,得到一个新的地址,而成员list的地址不会改变。如果需要得到一个完整的拷贝,需要用到深拷贝

示例如下

cool = ['blue', 'green', 'grey']
chill = cool[:]
chill.append('black')
print(chill)
print(cool)
['blue', 'green', 'grey', 'black']
['blue', 'green', 'grey']

浅拷贝和深拷贝

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,浅拷贝,list1和list2的地址不一样,但是共享了一片内存空间,list1[0]和list2[0]地址是一样的
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,深拷贝,list1和list2的地址不一样,且指向了不同的内存空间,任何修改都不会相互影响。
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]]

sort() 和 sorted的使用

当需要对list类型的数据进行排序时,会用到.sort()方法和sorted。
.sort()是没有返回值的,会改变list的内容。
sorted() 必须把结果赋值给另外的list变量,且并不会改变输入list变量。

#########################
## 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']

list的成员是list的情况

当list 的成员是list的时候,这个成员list仅仅保存了一个地址在整个list中。
此时使用append,传递的是一个成员list的地址。改变成员list的值,会影响到整体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']]

循环过程中修改list的情况

###############################
## 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]

猜你喜欢

转载自blog.csdn.net/s09094031/article/details/88634839