Python科学计算第二章 Python序列
概述
列表:可变,有序
元组:不可变,有序
字典:可变,无序 # Python3.7之后变为有序
集合:可变,无序
字符串:不可变,有序
range:不可变,有序
注意:zip, filter, enumerate, map不是序列而是迭代器,因此返回的对象不支持进行len,切片的操作(但可以正常进行max、sum操作,以及使用 sorted 函数排序(这些操作会消耗迭代器))
序列操作常用内置函数
1. all, any
all(序列):所有元素全True则返回True
any(序列):有元素True则返回True
2. len, max, min, sum
len(序列):返回序列中元素的个数
其余见第一章常用内置函数
3. zip, enumerate等
见第一章常用内置函数
列表 list
1. 列表创建
- lst = list(序列)
- lst = [元素1, 元素2, 元素3, ...]
2. + 列表连接与 * 列表扩展
+ 表示列表连接
例如:lst = lst1 + lst2
* 表示列表扩展
例如:lst = [1, 2, 3] * 3 # 结果为[1, 2, 3, 1, 2, 3]
注意乘号是复制列表的引用,不是直接复制原列表的值,例如:
x = [[None] * 2] * 3 # [[None, None], [None, None], [None, None]] x[0][0] = 5 # [[5, None], [5, None], [5, None]]3. 增删查改、逆序、排序
# 增 lst.append(元素) # 尾部追加元素 lst.extend(序列) # 尾部追加序列中所有元素 # 删 lst.remove(x) # 删除第一个值为x的元素,x不存在抛ValueError del lst[idx] # 使用del命令删除下标idx的元素 lst.pop(idx=-1) # 删除下标为idx的元素,默认为-1即最后一个,并返回该元素的值,索引超限抛IndexError # 查 lst.index(x) # 返回第一个值为x的元素的下标,x不存在抛ValueError lst[idx] # 返回下标idx元素,索引超限抛IndexError lst.count(x) # 返回x出现次数,未出现则为0 x in lst # in关键字查看x是否在列表中,不在False,在True # 改 lst.insert(idx, x) # 在下标idx插入x,插入后下标idx位置为x lst[idx] = newx # 下标idx元素修改为newx # 逆序 lst.reverse() # 原地操作,无返回值 # 排序 lst.sort(key=None, reverse=False) # 原地操作,无返回值,根据key排序,reverse为True则逆序 lst = sorted(lst, key=None) # 有返回值,使用内置函数对列表排序删除时的错误删法:
因迭代器会不断+1,而删除元素后后方元素会递补,导致迭代器和部分元素错过
正确删法:正确删法:
应该从后往前删
4. 切片方法
lst[起始:终止:步长]
左闭右开[起始,终止)
切片不会因下标越界抛出异常,会在列表尾部截断或返回空列表
在区间[起始,终止)按照步长切,要想切出元素则必须
- 起始 < 终止 且 步长为正
- 起始 > 终止 且 步长为负
起始位和终止位默认值(根据步长情况)
步长为正数或不填:起始默认0,终止默认len(lst)
步长为负数:起始默认-1,终止默认-len(lst)-1
若切片起始、终止均不填,只填了步长,形如lst[::步长],则切片情况如下(根据步长情况)
步长为空:-> 为lst[::],等价于lst[:],步长为1
步长为正数:-> 从 [0, len(lst)) 按步长切
步长为负数:-> 从[-1, -len(lst)-1) 按步长切(此时为倒着切)
做题时先把负下标转化成正下标:负下标 + len(lst) = 正下标
5. 用切片原地操作修改列表
# 增 lst[idx:idx] = lst2 # 在idx处插入lst2中所有元素 # 删 lst[切片] = [] # 删除被切到的值 del lst[切片] # 删除切片部分 # 改 lst[切片(连续,步长为1省略)] = lst2 # 将连续切片切到的部分改为lst2中元素 lst[切片(不连续)] = 和切到的部分元素个数一样多的列表 # 切片不连续两侧元素必须一样多,被切到的值一一对应改成右边列表中元素6. 切片只复制引用
如果原列表中只包含整数、实数、复数等基本类型或元组、字符串等不可变类型的数据,修改其中一个切片不会影响原列表和其它切片
如果有列表等可变序列,对它们进行修改则会影响原列表和其它切片
仅含整数与含整数、列表的列表的切片对比
根据引用对被引用的列表进行了操作
但指针的朝向不变
列表推导式
元组、字典、集合也有类似的推导式
1. 创建
lst = [表达式 for item in 可迭代对象]
2. 嵌套
列表推导式嵌套从左往右嵌套
# 假设有lstt列表,为列表的列表如[[1, 2, 3], [4, 5, 6], [7, 8, 9]] result = [a2 * a2 for a1 in lstt for a2 in a1] # 等价于 result = [] for a1 in lstt: for a2 in a1: result.append(a2 * a2)3. 条件判断
过滤条件、三元表达式,可以同时使用
# 过滤条件 lst = [表达式 for item in 可迭代对象 if 过滤条件表达式] # 可迭代对象中满足条件的经表达式处理放进列表中 # 三元表达式 lst = [表达式1 if 条件表达式 else 表达式2 for item in 可迭代对象] # 可迭代对象中所有,满足表达式则经表达式1处理,不满足经表达式2处理 # 同时使用过滤条件、三元表达式 lst = [表达式1 if 条件表达式 else 表达式2 for item in 可迭代对象 if 过滤条件表达式]4. 应用
矩阵转置:
matrix = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
# 下标i从0-3,分别构造里层列表,里层列表中元素为matrix中每个元素的第i个元素
T = [[item[i] for item in matrix] for i in range(4)]
求100以内素数:
# 筛选2-100中所有数p,满足对于从2-p^0.5的所有数d,p%d都不为0
[p for p in range(2, 100) if all(p%d for d in range(2, int(p**0.5)+1))]
元组 tuple
元组不可变,有序,用()表示
1. 元组创建
tup1 = tuple(序列)
tup1 = (元素1, 元素2, 元素3, ...)
2. 空元组与单元素元组
注意:单元素元组必须在元素后加上逗号,否则会退化成元素本身
空元组 tup1 =()
单元素元组 tup2 =(元素1,)
元组中存储的是引用
元组中包含可变对象的引用,这些对象可变,但引用不能改变
# 不改变引用的情形 x = ([1, 2, 3], 4) x[0].append(4) print(x) ''' ([1, 2, 3, 4], 4) ''' # 试图改变引用的情形,报错 x = ([1, 2, 3], 4) x[0] = x[0] + [4] # 此语句返回新列表,会改变原来的引用,报错 print(x) ''' 报错 '''字典 dict
字典可变,无序# Python3.7之后版本变为有序
字典中元素为键值对,键需为不可变的数据
1. 字典创建
dict1 = dict(键名1=值1, 键名2=值2, 键名3=值3, ...)
dict1 = {键1:值1, 键2:值2, 键3:值3, ...}
2. 空字典
dict1 ={}#表示空字典,注意与空集合 a = set() 区分
3. get, items, keys, values
dict1 = {'A':12, 'C':22, 'W':'S'} # get方法 # dict1.get(键名) # 返回键对应的值,键不存在返回None print(dict1.get('A')) print(dict1.get('B')) ''' 12 None ''' # dict1.get(键名, 默认返回值) # 返回键对应的值,键不存在返回默认值 print(dict1.get('A', 'mmmm')) print(dict1.get('B', 'mmmm')) ''' 12 mmmm ''' # items方法返回字典元素 for item in dict1.items(): print(item) ''' ('A', 12) ('C', 22) ('W', 'S') ''' # items配合序列解包 for key, value in dict1.items(): print(key, value) ''' A 12 C 22 W S ''' # keys方法返回字典的键 print(dict1.keys()) ''' dict_keys(['A', 'C', 'W']) ''' # 直接使用字典名默认使用字典的键 for key in dict1: print(key) ''' A C W ''' # values方法返回字典的值 print(dict1.values()) ''' dict_values([12, 22, 'S']) '''4. 元素增删改
使用指定键给字典赋值
键存在:修改其值
键不存在:创建新键值对
dict1 = {'A':12, 'C':22, 'W':'S'} print(dict1) ''' {'A':12, 'C':22, 'W':'S'} ''' dict1['A'] = 15 print(dict1) ''' {'A':15, 'C':22, 'W':'S'} ''' dict1['B'] = 22 print(dict1) ''' {'A':15, 'C':22, 'W':'S', 'B':22} '''update方法更新
dict1 = {'A':12, 'C':22, 'W':'S'} dict2 = {'A':17, 'B':21, 'K':'P'} # 将dict1更新dict2中的键值对,存在则修改,不存在则新增 dict1.update(dict2) print(dict1) ''' {'A':17, 'C':22, 'W':'S', 'B':21, 'K':'P'} '''元素删除del命令,pop, popitem
dict1 = {'A':12, 'C':22, 'W':'S', 'B':21, 'K':'P'} # del命令删除一个键值对 del dict1['A'] print(dict1) ''' {'C':22, 'W':'S', 'B':21, 'K':'P'} ''' # pop方法,根据键名删除键值对并返回一个值,可指定默认值 # dict1.pop(键名, 默认值) print(dict1.pop('C')) print(dict1) ''' 22 {'W':'S', 'B':21, 'K':'P'} ''' # popitem方法,随机删除一个键值对并返回元素(Python 3.7后弹出最后插入的键值对),空字典则KeyError print(dict1.popitem()) print(dict1) ''' 可能为: ('K', 'P') {'W': 'S', 'B': 21} '''集合set
集合可变,无序
1. 集合创建
set1 = set(序列)
set1 = {元素1, 元素2, 元素3, ...}
2. 空集合
空集合表示为set()# 注意与空字典区分
3. 删除
del set1 # del命令删除整个集合
set1.remove(元素) # 删除指定元素
set1.pop() # 随机删除并返回一个元素
4. 集合运算
&:交
| :并
^:对称差
-:差
例如
{1, 2, 3} & {3, 4, 5} = {3}
{1, 2, 3} | {3, 4, 5} = {1, 2, 3, 4, 5}
{1, 2, 3} ^ {3, 4, 5} = {1, 2, 4, 5}
{1, 2, 3} - {3, 4, 5} = {1, 2}
5. 包含关系
<:左为右的真子集
<=:左为右的子集
例如
{1} < {1, 2, 3} # True,为真子集
{1} <= {1, 2, 3} # True,为真子集,真子集也为子集
{1, 2, 3} < {1, 2, 3} # False,为子集但非真子集
{1, 2, 3} <= {1, 2, 3} # True,为子集
注意与列表、元组区分:列表、元组的<、<=为逐个元素依次比较,为比较关系
例如
(1, 2, 3) < (1, 3) # True,1=1,2<3
(1, 2, 3) < (1, 2, 3, -1) # True, 1=1,2=2,3=3,对应元素相等时,短元组小于长元组。
