十三、列表2
一、引用
列表引用,赋值的列表会追随原列表变化而变化
x = [1,2,3]
y = x
x[1] = 1
x
[1, 1, 3]
y
[1, 1, 3]
二、浅拷贝(copy)
1、copy
使用copy拷贝列表,赋值的列表不会追随原列表变化而变化。
copy方法拷贝的是整个列表对象,不仅仅是变量的引用。
x = [1,2,3]
y = x.copy()
x[1]=1
x
[1, 1, 3]
y
[1, 2, 3]
2、切片拷贝
y=x[:],其中[]中,:前后没写开始也没写结束,表示切的是整个列表。
x=[1,2,3]
y=x[:]
x[1]=1
x
[1, 1, 3]
y
[1, 2, 3]
三、深拷贝(嵌套列表)
1、当嵌套列表用copy方法时,赋值列表还是会随着原始列表的变化而变化。
x = [[1,2,3],[4,5,6],[7,8,9]]
y = x.copy()
x[1][1] = 0
x
[[1, 2, 3], [4, 0, 6], [7, 8, 9]]
y
[[1, 2, 3], [4, 0, 6], [7, 8, 9]]
因为浅拷贝只是拷贝了外层的对象,如果包含嵌套对象的话,那么拷贝的只是其引用。
2、使用copy模块的函数进行拷贝
1)浅拷贝—copy
import copy
x = [[1,2,3],[4,5,6],[7,8,9]]
y = copy.copy(x)
x[1][1] = 0
x
[[1, 2, 3], [4, 0, 6], [7, 8, 9]]
y
[[1, 2, 3], [4, 0, 6], [7, 8, 9]]
2)深拷贝—deepcopy
deepcopy函数将原对象拷贝的同时,也将对象中所有引用的子对象一并进行了拷贝。
x = [[1,2,3],[4,5,6],[7,8,9]]
y = copy.deepcopy(x)
x[1][1] = 0
x
[[1, 2, 3], [4, 0, 6], [7, 8, 9]]
y
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
四、列表推导式
1、列表推导式的效率通常要比循环语句快上一倍左右的速度。因为列表推导式在Python解释器里是以更快的C语言的速度来运行的。因此,比我们使用Python脚本的虚拟机pvm,里面以步进的速度来运行for循环要快很多。
举例:一个数值列表,如何将列表中的每个元素的值都变成原来的2倍?
oho = [1,2,3,4,5]
for i in range(len(oho)):
oho[i] = oho[i]*2
oho
[2, 4, 6, 8, 10]
使用列表推导式的方法:
oho = [1,2,3,4,5]
oho = [i * 2 for i in oho]
oho
[2, 4, 6, 8, 10]
2、基本语法:
[expression for target in iterable]
首先列表推导式的结果一定是个列表,所以要加上[],由于列表推导式的结果是使用一组数据来填充这个列表的,所以需要一个for语句来搭配,expression表达式相当于循环体。
x = [ i for i in range(10)]
x
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
x = [ i+1 for i in range(10)]
x
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
可以将列表推导式转换成循环
x = []
for i in range(10):
x.append(i+1)
x
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
3、列表推导式处理字符串
y = [c * 2 for c in "Love"]
y
['LL', 'oo', 'vv', 'ee']
4、将每一个字符都转换成对应的Unicode编码并保存为列表——ord内置函数
ord内置函数的作用是将单个字符串转换为对应的编码
code = [ord(c) for c in "Love"]
code
[76, 111, 118, 101]
5、二维列表提取数字——row是提取行
matrix = [[1,2,3],
[4,5,6],
[7,8,9]]
col2 = [row[1] for row in matrix] //取每行第二个值
col2
[2, 5, 8]
diag = [matrix[i][i] for i in range(len(matrix))] //取对角线的值
diag
[1, 5, 9]
循环是通过迭代来逐个修改原列表中的元素,而列表推导式则是直接创建一个新的列表,然后再赋值为原先的这个变量名。
6、创建一个嵌套列表
s = [[0] * 3 for i in range(3)]
s
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
s[1][1] = 1
s
[[0, 0, 0], [0, 1, 0], [0, 0, 0]]
7、列表推导式添加if筛选
语法:
[expression for target in iterable if condition]
even = [i for i in range(10) if i % 2 == 0]
even
[0, 2, 4, 6, 8]
语句的执行顺序如下:
8、筛选F开头的单词
fwords = [w for w in words if w[0]=='F']
fwords
['FishC', 'Fantastic']
五、列表推导式的嵌套
语法如下:
[expression for target1 in iterable1
for target1 in iterable2
…
for target1 in iterableN]
举例:将二维列表降级为一维列表
matrix = [[1,2,3],[4,5,6],[7,8,9]]
flatten = [col for row in matrix for col in row]
flatten
[1, 2, 3, 4, 5, 6, 7, 8, 9]
同理循环实现:
flatten = []
for row in matrix:
for col in row:
flatten.append(col)
flatten
[1, 2, 3, 4, 5, 6, 7, 8, 9]
外层循环放前面,内层循环放后面
笛卡尔乘积:
[x + y for x in "love" for y in "LOVE"]
['lL', 'lO', 'lV', 'lE', 'oL', 'oO', 'oV', 'oE', 'vL', 'vO', 'vV', 'vE', 'eL', 'eO', 'eV', 'eE']
_ = []
for x in "love":
for y in "LOVE":
_.append(x+y)
_
['lL', 'lO', 'lV', 'lE', 'oL', 'oO', 'oV', 'oE', 'vL', 'vO', 'vV', 'vE', 'eL', 'eO', 'eV', 'eE']
六、列表推导式的终极语法
语法如下:
[expression for target1 in iterable1 if condition1
for target1 in iterable2 if condition2
…
for target1 in iterableN if conditionN]
[[x,y] for x in range(10) if x % 2 ==0 for y in range(10) if y % 3 ==0]
[[0, 0], [0, 3], [0, 6], [0, 9], [2, 0], [2, 3], [2, 6], [2, 9], [4, 0], [4, 3], [4, 6], [4, 9], [6, 0], [6, 3], [6, 6], [6, 9], [8, 0], [8, 3], [8, 6], [8, 9]]
_=[]
for x in range(10):
if x%2==0:
for y in range(10):
if y%3==0:
_.append([x,y])
_
[[0, 0], [0, 3], [0, 6], [0, 9], [2, 0], [2, 3], [2, 6], [2, 9], [4, 0], [4, 3], [4, 6], [4, 9], [6, 0], [6, 3], [6, 6], [6, 9], [8, 0], [8, 3], [8, 6], [8, 9]]
七、程序设计原则:KISS
Keep It Simle & Stupid(简洁胜于复杂)