内置序列类型
按照序列存放元素方式的不同,可以分为:
-
容器序列:
list、 tuple 和 collections.deque
。 -
扁平序列:
str、 bytes、 bytearray、 memoryview 和 array.array
。容器序列中存放的是元素对象的引用,扁平序列存放的是值。所以前者能够存放不同类型的数据,而后者只能存放单一类型数据。
按照序列类型能否被修改,可以分为:
- 可变序列:
list、 bytearray、 array.array、 collections.deque 和 memoryview
。 - 不可变序列:
tuple、 str 和 bytes
。
列表推导和生成器表达式
列表推导仅限于list
对象的快捷构建,生成器表达式可以用于创建任何类型的序列。
列表推导
示例:
a = [i for i in 'ABC']
a = [i * j for i in range(10) for j in range(10)] # 计算笛卡尔积
生成器表达式
生成器表达式和列表推导语法相似,不同之处在于前者为圆括号,后者为方括号。
symbols = '$¢£¥€¤'
tuple(ord(symbol) for symbol in symbols)
元组
元组除了为不可变列表外,还具有如下理解。
-
元组的记录功能
lax_coordinates = (33.9425, -118.408056) city, year, pop, chg, area = ('Tokyo', 2003, 32450, 0.66, 8014) traveler_ids = [('USA', '31195855'), ('BRA', 'CE342567'), ('ESP', 'XDA205856')]
元组的记录功能体现在,元组可以将一个对象的所有信息打包起来,这样这些信息就和对象个体实现了绑定的操作,在多个对象间进行操作时,不会将个体所携带的信息丢失。
-
元组拆包
普通拆包操作如下:
lax_coordinates = (33.9425, -118.408056) latitude, longitude = lax_coordinates # 元组拆包
*
运算符,将可迭代对象拆开作为函数参数。t = (1, 2) func(*t) // 等同func(1, 2)
*args
获取不确定数量参数。>>> a, b, *rest = range(5) >>> a, b, rest (0, 1, [2, 3, 4]) >>> a, *body, c, d = range(5) >>> a, body, c, d (0, [1, 2], 3, 4)
-
嵌套元组拆包
i, j, (k, l) = (1, 2, (3, 4))
-
具名元组
>>> from collections import namedtuple >>> City = namedtuple('City', 'name country population coordinates') >>> tokyo = City('Tokyo', 'JP', 36.933, (35.689722, 139.691667)) >>> tokyo City(name='Tokyo', country='JP', population=36.933, coordinates=(35.689722, 139.691667)) >>> tokyo.population 36.933 >>> tokyo.coordinates (35.689722, 139.691667) >>> tokyo[1] 'JP
具名元组可以理解为一个只有属性没有方法的类对象,创建时接收两个参数:一个是类名,一个是类的各个属性的名字。
高级切片
-
间隔取值
>>> s = 'bicycle' >>> s[::3] 'bye' >>> s[::-1] 'elcycib' >>> s[::-2] 'eccb'
s[a:b:c]
的形式对s
在a
和b
之间以c
为间隔取值。c
的值为负表示反向取值。 -
多维切片和省略符
[a:b, c:d, e:f]
三维切片。x[i, ...]
为x[i, :, :, :]
的缩写。 -
切片赋值
>>> l = list(range(10)) >>> l [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> l[2:5] = [20, 30] >>> l [0, 1, 20, 30, 5, 6, 7, 8, 9] >>> del l[5:7] >>> l [0, 1, 20, 30, 5, 8, 9] >>> l[3::2] = [11, 22] >>> l [0, 1, 20, 11, 5, 22, 9] >>> l[2:5] = [100] >>> l [0, 1, 100, 22, 9]
如果赋值对象是一个切片,
=
右边也必须是个可迭代对象。
list.sort方法和内置函数sorted
list.sort
方法是对列表对象就地改动,即不会返回新列表,而是直接对原列表改变。内置函数sorted
会新建一个列表返回。
用bisect来管理已排序的序列
bisect.bisect(seq, item)
返回元素item
插入到已排序序列seq
中的位置索引。如果item
在seq
中已出现,那么插入到那个出现的值的右侧,bisect_left
插入在左侧。
bisect.insort(seq, item)
返回item
插入序列seq
中,并保持整个序列升序。
其他序列类型
-
数组(array)
对于只存放数字的序列,array比list更高效。
-
内存视图(memoryview)
用户可以在不复制内容的情况下操作同一个数组的不同切片。
-
双向队列(collections.deque)
双向队列,一个能够从两端添加或者删除元素的序列类型。对于大小固定的队列,满员后添加一个元素会在反向端删除一个元素。
>>> from collections import deque >>> dq = deque(range(10), maxlen=10) >>> dq deque([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], maxlen=10) >>> dq.rotate(3) >>> dq deque([7, 8, 9, 0, 1, 2, 3, 4, 5, 6], maxlen=10) >>> dq.rotate(-4) >>> dq deque([1, 2, 3, 4, 5, 6, 7, 8, 9, 0], maxlen=10) >>> dq.appendleft(-1) >>> dq deque([-1, 1, 2, 3, 4, 5, 6, 7, 8, 9], maxlen=10) >>> dq.extend([11, 22, 33]) >>> dq deque([3, 4, 5, 6, 7, 8, 9, 11, 22, 33], maxlen=10) >>> dq.extendleft([10, 20, 30, 40]) >>> dq deque([40, 30, 20, 10, 3, 4, 5, 6, 7, 8], maxlen=10)
-
队列(queue)
与双向列表不同,固定大小的队列满员后,其中元素将被锁住无法进行添加,知道某个线程移除某个元素腾出位置。