一、数据结构
第一章 序列构成的数组
1.1 内置序列类型概述
容器序列:list、tuple和collections.deque这些序列能存放不同类型的数据。
扁平序列:str、bytes、bytearray、memoryview和array.array,这些序列只能容纳一种类型。
可变序列:list、bytearray、array.array、collections.deque和memoryview。
不可变序列:tuple、str和bytes。
1.2 列表推导和生成器表达式
1.2.1 列表推导和可读性
2-1 把字符串变成Unicode码位的列表
python
# 方法一
sysmbols = '$¥&*#@!'
codes = []
for symbol in sysmbols:
codes.append(ord(symbol))
print(codes)
# 方法二
sysmbols = '$¥&*#@!'
codes = [ord(symbol) for symbol in sysmbols]
print(codes)
# 结果
[36, 65509, 38, 42, 35, 64, 33]
[36, 65509, 38, 42, 35, 64, 33]
**句法提示:**python会忽略代码里[]、{}、()中的换行,因此如果你的代码里有多行的列表、列表推导、生成器表达式、字典这一类的,可以省略不太好看的续行符\。
2-2 列表推导不会再有变量泄露的问题
python
# 列表推导、生成器表达式、集合推导、字典推导,在python3中有自己局部作用域,不会影响同名变量。
x = 'ABC'
dummy = [ord(x) for x in x]
print(x)
print(dummy)
# 结果
ABC
[65, 66, 67]
1.2.2 列表推导同filter和map的比较
2-3 列表推导和map/filter组合结果相同,明显列表推导更简单
python
sysmbols = '$¥&*#@!'
beyond_ascii = [ord(s) for s in sysmbols if ord(s) > 127]
print(beyond_ascii)
beyond_ascii2 = list(filter(lambda c: c > 127, map(ord, sysmbols)))
print(beyond_ascii2)
# 结果
[65509]
[65509]
1.2.3 笛卡儿积
2-4 使用列表推导计算笛卡儿积
python
colors = ['black', 'white']
sizes = ['S', 'M', 'L']
tshirts = [(color, size) for size in sizes
for color in colors]
print(tshirts)
# 结果
[('black', 'S'), ('white', 'S'), ('black', 'M'), ('white', 'M'), ('black', 'L'), ('white', 'L')]
列表推导的作用只有一个:生成列表
1.2.4 生成器表达式
2-5 用生成器表达式初始化元组和数组
python
sysmbols = '$¥&*#@!'
tup = tuple(ord(symbol) for symbol in sysmbols)
print(tup)
import array
arr = array.array('I', (ord(symbol) for symbol in sysmbols))
print(arr)
# 结果
(36, 65509, 38, 42, 35, 64, 33)
array('I', [36, 65509, 38, 42, 35, 64, 33])
2-6 使用生成器表达式计算笛卡儿积
生成器表达式逐个产出元素,不会一次性产出所有列表,避免额外的内存占用。
python
colors = ['black', 'white']
sizes = ['S', 'M', 'L']
for tshirt in ('%s, %s,' %(c, s) for c in colors for s in sizes):
print(tshirt)
# 结果
black, S,
black, M,
black, L,
white, S,
white, M,
white, L,
1.3 元组不仅仅是不可变的列表
1.3.1 元组和记录
2-7 把元组用作记录
python
lax_coordinates = (33.9425, -118.408056)
city, year, pop, chg, area = ('Tokyo', 2003, 32450, 0.66, 8041)
traveler_ids = [('USA', '31195855'), ('BRA', 'CE342567'), ('ESP', 'XDA205856')]
for passport in sorted(traveler_ids): #迭代过程中,passport变量被绑定到每个元组上
print('%s/%s' %passport)
for country, _ in traveler_ids: #拆包(unpacking),元组中第二个元组没用,用占位符"_"
print(country)
# 结果
BRA/CE342567
ESP/XDA205856
USA/31195855
USA
BRA
ESP
1.3.2 元组拆包
python
lax_coordinates = (33.9425, -118.408056)
latitude, longitude = lax_coordinates # 元组拆包
print(latitude, longitude)
dm = divmod(20, 8)
print(dm)
t = (20, 8)
dm2 = divmod(*t) # 用*运算符把一个可迭代对象拆开作为函数的参数
print(dm2)
quotient, remainder = divmod(*t)
print(quotient, remainder)
# 结果
33.9425 -118.408056
(2, 4)
(2, 4)
2 4
os.path.split()函数会返回以路径和最后一个文件名组成的元组(path, last_part)
python
import os
path, filename = os.path.split('D:\pythonProject\Fluent_Python\Data_Structure\\array\\tuple.py')
print(path)
print(filename)
# 结果
D:\pythonProject\Fluent_Python\Data_Structure\array
tuple.py
用 * 来处理剩下的元素
python
a, b, *rest = range(5)
print(a, b, rest)
a, b, *rest = range(3)
print(a, b, rest)
a, b, *rest = range(2)
print(a, b, rest)
a, *body, c, d = range(5) # 在平行赋值中,*前缀只能用在一个变量名前,但是这个变量可以出现在复制表达式的任意位置
print(a, body, c, d)
*head, b, c, d = range(5)
print(head, b, c, d)
# 结果
0 1 [2, 3, 4]
0 1 [2]
0 1 []
0 [1, 2] 3 4
[0, 1] 2 3 4