Python--序列
1.序列类型
容器序列
list、tuple 和 collections.deque 这些序列能存放不同类型的数据。
扁平序列
str、bytes、bytearray、memoryview 和 array.array,这类序列只能容纳一种类型。
序列类型还能按照能否被修改来分类。
可变序列
list、bytearray、array.array、collections.deque 和 memoryview。
不可变序列
tuple、str 和 bytes。
2.filter 和 map 合起来能做的事情,列表推导也可以做。
3.生成器表达式的语法跟列表推导差不多,只不过把方括号换成圆括号而已。
symbols = 'string'
tuple(ord(symbol) for symbol in symbols)
4.具名元组
collections.namedtuple 是一个工厂函数,它可以用来构建一个带字段名的元组和一个有名字的类
定义和使用具名元组:
from collections import namedtuple City = namedtuple('City', 'name country population coordinates') #创建具名元组类,参数:(类名,类的各个字段的名字) tokyo = City('Tokyo', 'JP', 36.933, (35.689722, 139.691667)) print(tokyo) #City(name='Tokyo', country='JP', population=36.933, coordinates=(35.689722,139.691667)) print(tokyo.population) #通过字段名来获取一个字段的信息 #36.933 print(tokyo[1]) #通过位置来获取一个字段的信息 #JP print(City._fields ) #获取所有字段名称 #('name', 'country', 'population', 'coordinates') LatLong = namedtuple('LatLong', 'lat long') delhi_data = ('Delhi NCR', 'IN', 21.935, LatLong(28.613889, 77.208889)) delhi = City._make(delhi_data) #通过接受一个可迭代对象来生成实例,它的作用跟City(*delhi_data) 是一样的。 print(delhi._asdict()) #把具名元组以 collections.OrderedDict 的形式返回 #OrderedDict([('name', 'Delhi NCR'), ('country', 'IN'), ('population',21.935), ('coordinates', LatLong(lat=28.613889, long=77.208889))])
5.列表或元组的其它方法和属性
s.__add__(s2) # s + s2,拼接 s.__iadd__(s2) # s += s2,就地拼接 s.__contains__(e) # s 是否包含 e s.copy() # 列表的浅复制 s.__delitem__(p) # 把位于 p 的元素删除 s.__getitem__(p) #s[p],获取位置 p 的元素 s.__getnewargs__() #在 pickle 中支持更加优化的序列化 s.__iter__() # 获取 s 的迭代器 s.__mul__(n) # s * n,n 个 s 的重复拼接 s.__imul__(n) # s *= n,就地重复拼接 s.__rmul__(n) # n * s,反向拼接 * s.__reversed__() # 返回 s 的倒序迭代器 s.__setitem__(p, e) # s[p] = e,把元素 e 放在位置p,替代已经在那个位置的元素
6.切片
用 s[a:b:c] 的形式对 s 在 a 和 b 之间以 c 为间隔取值。c 的值还可以为负,负值意味着反向取值。
s = 'bicycle' >>> s[::3] 'bye' >>> s[::-1] 'elcycib'
切片赋值:
l = list(range(10)) print(l) #[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] l[2:5] = [20, 30] print(l) #[0, 1, 20, 30, 5, 6, 7, 8, 9] del l[5:7] print(l) #[0, 1, 20, 30, 5, 8, 9] l[3::2] = [11, 22] print(l) #[0, 1, 20, 11, 5, 22, 9] l[2:5] = [100] print(l) #[0, 1, 100, 22, 9]
7.对序列使用+和*
+ 和 * 不修改原有的操作对象,而是构建一个全新的序列。
l = [1, 2, 3] print( l * 5) #[1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]
8.sort和sorted方法
list.sort 方法会就地排序列表,也就是说不会把原列表复制一份。这是这个方法的返回值是 None 的原因,提醒你本方法不会新建一个列表。random.shuffle 函数也遵守了这个惯例。
内置函数 sorted,它会新建一个列表作为返回值。
不管是 list.sort 方法还是 sorted 函数,都有两个可选的关键字参数。
reverse
这个参数的默认值是 False。
key
排序算法依赖的对比关键字。这个参数是默认用元素自己的值来排序。
比如key=str.lower 来实现忽略大小写的排序;key=len 进行基于字符串长度的排序。
9.bisect模块
作用:用bisect来管理已排序的序列
bisect 模块包含两个主要函数bisect 和 insort,两个函数都利用二分查找算法来在有序序列中查找或插入元素。
查找:bisect.bisect(seq, needle) 查找位置 index
bisect 函数其实是 bisect_right 函数的别名,返回的则是跟它相等的元素之后的位置。
它还有个姊妹函数叫 bisect_left。
插入:bisect.insort(seq, item) 把变量 item 插入到序列 seq 中,并能保持 seq 的升序顺序。
使用时,用seq.insert(index, needle) 来插入新值,也可用该 insort 来一步到位。
根据一个分数,找到它所对应的成绩:
def grade(score, breakpoints=[60, 70, 80, 90], grades='FDCBA'): i = bisect.bisect(breakpoints, score) return grades[i] ret=[grade(score) for score in [33, 99, 77, 70, 89, 90, 100]] print(ret) #['F', 'A', 'C', 'C', 'B', 'A', 'A']
10.双向队列
collections.deque基本上实现了List的常用方法,在这个基础上又添加了它的新特性,值得一提的是list的l.insert(0,v)和l.pop(0)的操作(再列表的头部进行插入或删除)的时间复杂度是O(n),随着元素增加耗时呈线性上升的,而deque的这两个操作的时间复杂度是O(1)的,所以当代码对此类操作有性能需求时,用deque再好不过了。
格式:deque([iterable[, maxlen]]) --> deque object
说明:deque可接收两个参数,第一个参数iterable必须是一个可迭代对象,第二个参数是一个可选参数,maxlen设置序列的最大长度,当有新的记录加入而队列已满时会自动移动除最老的那条记录。
dq = deque(range(10)) print(dq) # deque([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) #在序列的左侧添加一个元素 dq.appendleft(-1) print(dq) # deque([-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) #通过从可迭代的对象的元素来扩展 deque 的左侧 dq.extendleft(range(100,103)) print(dq) # deque([103, 102, 101, 100, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) #移除并返回序列最左侧的元素 ret = dq.popleft() print(ret) # 103 print(dq) # deque([102, 101, 100, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) #n为正数则将右边的数据移动到序列的左边,n为负数则将左边的数据移动到序列的右边 dq.rotate(2) print(dq) # deque([8, 9, 102, 101, 100, -1, 0, 1, 2, 3, 4, 5, 6, 7]) dq.rotate(-4) print(dq) # deque([100, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 102, 101])