一、概述
序列类型(Sequence Types)类似于C中的数组,它是包含一组成员的连续列表,这些成员紧邻排列,并且可以通过序号(下标偏移量)访问其中的一个或多个成员。序列类型的示意图如下所示:
Python中最核心的序列类型共有3种:字符串(str和unicode)、列表(list)和元组(tuple)。
二、操作
序列类型支持的主要操作如下:
操作 | 说明 |
---|---|
s[i] | s中第i个成员(从0开始) |
s[i:j] | s中从i到j的切片 |
s[i:j:k] | s中从i到j的切片,步长为k |
s * n, n * s | s的n份(浅)拷贝的串联 |
s + t | s与t的串联 |
x in s | 如果x是s的成员,为True;否则,为False |
x not in s | 如果x是s的成员,为False;否则,为True |
enumerate(s) | 返回一个enumerate对象,该对象生成由(i, s[i])组成的元组 |
len(s) | s的长度 |
list(iter) | 把可迭代对象转换为列表 |
max(s) | s中的最大值 |
min(s) | s中的最小值 |
reversed(s) | 返回一个迭代器,访问该迭代器得到的序列与s逆序 |
sorted(s) | 返回一个列表,该列表是对s排序后的结果 |
str(obj) | 把对象转换为字符串(对象的字符串表示) |
sum(s[, start]) | s中成员与start的总和(只能用于数值列表或数值元组,字符串用''.join(s)) |
tuple(iter) | 把可迭代对象转换为元组 |
unicode(obj) | 把对象转换为Unicode字符串(使用默认编码) |
zip(s1, s2, ...) | 返回一个列表:[(s1[0], s2[0], ...), (s1[1], s2[1], ...), ...] |
以上操作的示例如下:
>>> s = 'abcedf'
>>> l = [0, 1, 2, 3, 4, 5]
>>> t = tuple(l)
>>>
>>> s[0], l[0], t[0]
('a', 0, 0)
>>> s[2:5], l[2:5], t[2:5]
('ced', [2, 3, 4], (2, 3, 4))
>>> s[2:5:2], l[2:5:2], t[2:5:2]
('cd', [2, 4], (2, 4))
>>> s * 2, 2 * s
('abcedfabcedf', 'abcedfabcedf')
>>> list(s) + l
['a', 'b', 'c', 'e', 'd', 'f', 0, 1, 2, 3, 4, 5]
>>> 6 in l, 6 not in l
(False, True)
>>>
>>> for i, x in enumerate(s):
... print i, x
...
0 a
1 b
2 c
3 e
4 d
5 f
>>> len(s), len(l), len(t)
(6, 6, 6)
>>> max(s), min(s)
('f', 'a')
>>> for x in reversed(t):
... print x,
...
5 4 3 2 1 0
>>> sorted([7, 4, 8, 0, 9])
[0, 4, 7, 8, 9]
>>> str(t)
'(0, 1, 2, 3, 4, 5)'
>>> unicode(l)
u'[0, 1, 2, 3, 4, 5]'
>>> sum(t), sum(t, 5)
(15, 20)
>>> zip(s, l, t)
[('a', 0, 0), ('b', 1, 1), ('c', 2, 2), ('e', 3, 3), ('d', 4, 4), ('f', 5, 5)]
三、切片
1、[]
“[]”用于访问序列中的单个元素,如可以用s[i]访问序列s中的第i个元素,其中对i的取值范围有以下限制:
- 如果i非负,则i必须在[0, N-1]范围内,否则访问会引发越界异常
- 如果i为负,则i必须在[-N, -1]范围内,否则访问会引发越界异常
以上描述中,N=len(s)即序列的长度。
序列的 下标编号规则 参考『概述』一节中的“序列类型示意图”,实际上,对于序列s而言:
- i非负时,Python使用s[i]去访问序列
- i为负时,Python使用s[N+i]去访问序列
“[]”的操作示例如下:
>>> s = 'abcdef' # N=len(s)等于6,因此非负i的范围[0, 5],负i的范围[-6, -1]
>>>
>>> s[0] # 0非负,且0在[0, 5]范围内
'a'
>>>
>>> s[6] # 0非负,但6>5,越界异常
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: string index out of range
>>>
>>> s[-1] # -1为负,且-1在[-6, -1]范围内
'f'
>>>
>>> s[-7] # -7为负,但-7<-6,越界异常
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: string index out of range
2、[:]和[::]
“[:]”和“[::]”用于访问序列中的多个元素(又称切片,slice),因为在功能上“[:]”完全可以看作是“[::1]”(即步长为1)的简写,所以理解“[::]”是掌握切片操作的关键。
切片s[i:j:k]是一个子序列,它由序列s中下标在 [i, j)(左闭右开区间)范围内的一些成员构成,这些成员的下标分别为i, i+k, i+2*k, ...。
在切片操作中,i、j、k的取值有以下特点(具体细节可以参考 Python2.7.5源码 的Python-2.7.5/Objects/sliceobject.c中的PySlice_GetIndicesEx函数):
- k不能为0;省略k或k为None时,令k=1
- k为正时
- 如果省略i或i为None,则令i=0
- 如果省略j或j为None,则令j=N
- 如果i为负,则令i=i+N,此时如果i仍然为负,则令i=0;j类似
- 如果i大于等于N,则令i=N;j类似
- k为负时
- 如果省略i或i为None,则令i=N-1
- 如果省略j或j为None,则令j=-1
- 如果i为负,则令i=i+N,此时如果i仍然为负,则令i=-1;j类似
- 如果i大于等于N,则令i=N-1;j类似
特别地,经过上述计算后,如果i、j、k的最终取值满足以下情况,则切片s[i:j:k]对应的子序列为空:
- k为正,且i大于等于j
- k为负,且i小于等于j
“[:]”和“[::]”的操作示例如下:
>>> s = 'abcdef' # N=len(s)等于6
# 1. 省略k或k为None时,k=1
>>> s[0:4], s[0:4:None], s[0:4:1]
('abcd', 'abcd', 'abcd')
# 2. k为正时
>>> s[:2] # 省略i时,令i=0,因此s[:2]等价于s[0:2]
'ab'
>>> s[2:] # 省略j时,令j=N,因此s[2:]等价于s[2:6]
'cdef'
>>> s[2:-1] # j为负时,令j=-1+N,因此s[2:-1]等价于s[2:5]
'cde'
>>> s[2:-10] # j为负时,j=-10+N等于-4仍然为负,令j=0,因此s[2:-10]等价于s[2:0]
''
>>> s[10:2] # i大于N时,令i=N,因此s[10:2]等价于s[6:2]
''
# 3. k为负时
>>> s[:2:-1] # 省略i时,令i=N-1,因此s[:2:-1]等价于s[5:2:-1]
'fed'
>>> s[2::-1] # 省略j时,令j=-1,因此s[2::-1]的成员为s[2]、s[1]、s[0],但不等价于s[2:-1:-1]
'cba'
>>> s[2:-1:-1] # j为负时,令j=-1+N,因此s[2:-1:-1]等价于s[2:5:-1]
''
>>> s[2:-10:-1] # j为负时,j=-10+N等于-4仍然为负,令j=-1,因此s[2:-10:-1]等价于s[2::-1]
'cba'
>>> s[10:2:-1] # i大于N时,令i=N-1,因此s[10:2:-1]等价于s[5:2:-1]
'fed'
>>> s, s[:], s[0:6], s[::], s[0:6:None], s[0:6:1] # 序列s的各种等价表示
('abcdef', 'abcdef', 'abcdef', 'abcdef', 'abcdef', 'abcdef')
>>>
>>> s[::-1] # 序列s的逆序表示
'fedcba'