python4:序列概览
Python中的序列类型包括list、tuple、range、二进制数据、text和string,这里对序列的公共操作做一个介绍,后面将陆续介绍每一种序列类型。
公共序列操作
所有序列类型都可以近些某些特定的操作,包括:索引、分片、加、乘、计算序列长度、最大值、最小值等操作。
索引
序列中的每个元素被分配一个序号,第一个索引为0,第二个为1,依次类推。假定s是一个序列,s[i]即表示是的第i个元素,i大于0且小于s的长度,看下面的例子:
>>> s = ‘Hello‘
>>> s[0]
‘H‘
>>> ‘Hello‘[1]
‘e‘
s[i]中i也可以是负数,这是Python会从右边,也就是最后1个元素开始计数,最后一个元素的编号是-1(不是-0,因为那会和第1个元素重合),例如:
>>> ‘Hello‘[-1]
‘o‘
>>> ‘Hello‘[-4]
‘e‘
分片
分片操作可以访问一定范围内的元素,s[i:j]表示访问[i,j)范围的元素,例如:
>>> s = [1,2,3,4,5,6,7,8,9,10]
>>> s[3:6]
[4, 5, 6]
需要注意i包含在分片内,而j不包含在分片内。你也可以不指定开始和结尾,例如:
>>> s[8:]
[9, 10]
>>> s[:4]
[1, 2, 3, 4]
>>> s[:]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
你同样可以使用负索引:
>>> s[-3:]
[8, 9, 10]
但需要注意的是,如果使用了索引-1,则最后一个元素无法访问,你只能使用上面的方法访问最后一个元素:
>>> s[-3:-1]
[8, 9]
>>> s[-3:0]
[]
你还可以指定步长,就是使用第3个参数:s[i:j:step],分片操作将按照这个步长便利序列的元素,然后返回开始和结束点之间的所有元素:
>>> s[0:10:2]
[1, 3, 5, 7, 9]
>>> s[1:10:2]
[2, 4, 6, 8, 10]
或者:
>>> s[::2]
[1, 3, 5, 7, 9]
步长可以为负,这时表示从右向左提取元素:
>>> s[8:3:-2]
[9, 7, 5]
>>> s[::-2]
[10, 8, 6, 4, 2]
序列加
假定序列s和t,s + t表示两个序列相加:
>>> [1,2,3] + [4,5,6]
[1, 2, 3, 4, 5, 6]
>>> ‘Hello. ‘ + ‘world!‘
‘Hello. world!
不同类型的序列相加将导致异常。需要注意如果序列为不可变序列,则序列相加的结果将是生成一个新的序列,将带来一定的代价。
乘法
序列s和数字n相乘,即s * n,会生成新的序列,在新的序列中,原来的序列被重复n次,例如:
>>> [42] * 5
[42, 42, 42, 42, 42]
注意空序列[] * n任然为空序列[],如果想生成一个长度为n的序列,可以用下面的方法:
>>> s = [None] * 10
>>> s
[None, None, None, None, None, None, None, None, None, None]
None是Python的内建值,表示“这里什么也没有”。
对于嵌套序列需要注意,看下面的例子:
>>> lists = [[]] * 3
>>> lists
[[], [], []]
>>> lists[0].append(3)
>>> lists
[[3], [3], [3]]
出现这种结果的根本原因是lists的第2和3个元素和第1个元素引用的是同一个序列,如果要避免这种情况,可以使用下面的方法:
>>> lists = [[] for i in range(3)]
>>> lists[0].append(3)
>>> lists[1].append(5)
>>> lists[2].append(7)
>>> lists
[[3], [5], [7]]
in和not in
in运算符用于检查一个值是否在序列中,not in则这行相反的操作,两者的使用方法一致。下面是一些例子:
>>> s = ‘Hello‘
>>> ‘e‘ in s
True
>>> ‘ee‘ in s
False
>>> ‘ee‘ not in s
True
>>> lists = [‘mine‘,‘yours‘,‘his‘]
>>> input(‘This is ‘) in lists
This is mine
True
长度、最大值和最小值
假定s是一个序列,len(s)计算s的长度,min(s)返回s的最小值,max(s)返回s的最大值。
>>> numbers = [10,20,30]
>>> len(numbers)
3
>>> max(numbers)
30
>>> min(numbers)
10
>>> max(2,3,4)
4
>>> min(3,4,1,2)
1
index
s.index(x)返回x在s中第一次出现的位置。
>>> s = ‘Thank you!‘
>>> s.index(‘an‘)
2
>>> [1,2,3,4].index(3)
2
你也可以使用s.index(x,i)指定起始位置。
>>> s *= 2
>>> s
‘Thank you!Thank you!‘
>>> s.index(‘an‘)
2
>>> s.index(‘an‘,4)
12
还可以使用s.index(x,i,j)同时指定起始和结束位置。
>>> numbers = [1,2,3] * 3
>>> numbers
[1, 2, 3, 1, 2, 3, 1, 2, 3]
>>> numbers.index(2)
1
>>> numbers.index(2,5,8)
7
需要注意的是如果x不在s中的[i,j)返回内,将抛出ValueError,例如下面的例子:
>>> numbers.index(2,5,7)
Traceback (most recent call last):
File "<pyshell#15>", line 1, in <module>
numbers.index(2,5,7)
ValueError: 2 is not in list
>>> s.index(‘an‘,14)
Traceback (most recent call last):
File "<pyshell#18>", line 1, in <module>
s.index(‘an‘,14)
ValueError: substring not found
count
s.count(x)返回x在s中出现的次数。
>>> s = ‘Thank you!‘
>>> s *= 5
>>> s
‘Thank you!Thank you!Thank you!Thank you!Thank you!‘
>>> s.count(‘an‘)
5
>>> s.count(‘aaa‘)
0
不可变序列
仅有的在不可变序列中实现而没在可变序列中实现的操作是hash()方法,这样就允许不可变序列,例如tuple,被用于字典的key和存储在set中。
注意尝试哈希一个包含不可哈希值的不可变队列将导致TypeError。
可变队列
可变队列支持队列的添加、删除和修改操作。
赋值
可以使用索引标记来为某个元素赋值,例如:
>>> s = [1,1,1]
>>> s[1] = 2
>>> s
[1, 2, 1]
对不存在的元素进行复制,将导致IndexError。
>>> s[3] = 4
Traceback (most recent call last):
File "<pyshell#28>", line 1, in <module>
s[3] = 4
IndexError: list assignment index out of range
可以s[i:j]=t对某个区间进行赋值,t必须是一个迭代器。
>>> s *= 3
>>> s
[1, 2, 1, 1, 2, 1, 1, 2, 1]
>>> s[2:5] = [10,10,10]
>>> s
[1, 2, 10, 10, 10, 1, 1, 2, 1]
>>> other = [3] * 5
>>> s[:4] = other
>>> s
[3, 3, 3, 3, 3, 10, 1, 1, 2, 1]
>>> s[-5:] = other
>>> s
[3, 3, 3, 3, 3, 3, 3, 3, 3, 3]
你甚至可以指定赋值的步长。
>>> s = [1] * 10
>>> s[2:9:2] = [5,6,7,8]
>>> s
[1, 1, 5, 1, 6, 1, 7, 1, 8, 1]
前面讲到的分片的技巧在这里都可以使用。
删除元素
使用del语句来删除序列中的元素,del可以删除单个元素,也可以删除区间数据,如下:
>>> names = [‘Alice‘,‘Beth‘,‘Cecil‘,‘Dee-Dee‘,‘Earl‘]
>>> del names[2]
>>> names
[‘Alice‘, ‘Beth‘, ‘Dee-Dee‘, ‘Earl‘]
>>> del names[1:3]
>>> names
[‘Alice‘, ‘Earl‘]
del操作也可以指定步长。
>>> names = [‘Alice‘,‘Beth‘,‘Cecil‘,‘Dee-Dee‘,‘Earl‘]
>>> del names[::2]
>>> names
[‘Beth‘, ‘Dee-Dee‘]
del也能用于字典元素甚至是其他变量的删除操作,在后面介绍。
append和pop
append用于添加元素到序列的结尾,pop则是从序列中移除一个元素。下面看append的操作:
>>> s = [1,2,3]
>>> s.append(4)
>>> s
[1, 2, 3, 4]
pop(i)中i的默认值为-1,因此默认移除最后一个元素,并返回移除的元素的值:
>>> s.pop()
4
>>> s
[1, 2, 3]
>>> s.pop(1)
2
>>> s
[1, 3]
注意append和pop只是在恰当位置修改原来的列表。
insert
insert(i,x)用于将x插入到序列指定的位置:
>>> s = [1,2,3,4,5,6,7,8,9,10]
>>> s.insert(5,‘error‘)
>>> s
[1, 2, 3, 4, 5, ‘error‘, 6, 7, 8, 9, 10]
insert方法可以使用分片赋值来实现:
>>> s = [1,2,3,4,5,6]
>>> s[3:3] = [‘error‘]
>>> s
[1, 2, 3, ‘error‘, 4, 5, 6]
这样的后果就是可读性不如insert更好。
extend
extend(t)使用t来扩展序列s,t是另一个序列,即使用新序列来扩展原有的序列:
>>> a = [1,2,3]
>>> b = [4,5,6]
>>> a.extend(b)
>>> a
[1, 2, 3, 4, 5, 6]
这个操作很像a+b的操作,但extends修改了被扩展的序列,即a,而a+b的操作则是返回一个全新的列表,a和b都没有被改变,因此a+b的效率会比extend的效率低。
我们也可以使用分片赋值来实现相同的结果:
[1, 2, 3, 4, 5, 6]
>>> a = [1,2,3]
>>> b = [4,5,6]
>>> a[len(a):] = b
>>> a
[1, 2, 3, 4, 5, 6]
同样,这样的可读性不如extend更好。
remove
remove(x)移除序列中x的第一个匹配项。
>>> s = [1,2,3] * 3
>>> s.remove(2)
>>> s
[1, 3, 1, 2, 3, 1, 2, 3]
只有第一个出现的值被移除了,如果移除的值不在序列中,则抛出ValueError异常。
>>> s.remove(4)
Traceback (most recent call last):
File "<pyshell#86>", line 1, in <module>
s.remove(4)
ValueError: list.remove(x): x not in list
remove也是一个原位置改变方法,无返回值。
clear
clear()移除序列中的所有元素。
>>> s = [1,2,3] * 3
>>> s.clear()
>>> s
[]
也可以使用del操作来达到clear的效果,但可读性不如clear:
>>> s = [1,2,3] * 3
>>> del s[:]
>>> s
[]
copy
copy()创建一个序列的浅拷贝。
>>> s = [1,2,3,4,5,6]
>>> c = s.copy()
>>> c.append(7)
>>> s
[1, 2, 3, 4, 5, 6]
>>> c
[1, 2, 3, 4, 5, 6, 7]
但需要注意只是浅拷贝,看下面的例子:
>>> s = [[1],[2],[3]]
>>> c = s.copy()
>>> c[1].append(5)
>>> c
[[1], [2, 5], [3]]
>>> s
[[1], [2, 5], [3]]
由于只是浅拷贝,c中元素和s中元素指向的是相同的序列,因此导致这样的结果。
reverse
reverse()方法将队列中的元素反向存放,该方法改变列表不返回值。
>>> s = [1,2,3]
>>> s.reverse()
>>> s
[3, 2, 1]
小结
到这里,序列的基本操作就介绍完毕了,这些基本操作是序列的基础,后面介绍的序列类型都可使用这些操作(区分不可变序列和可变序列)。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。