数据结构是通过某种方式(例如对元素进行编号) 数据结构,在Python中,最基本的数据结构是序列(sequence).序列中的每个元素分配一个序号->元素的位置,也称为索引.第一个索引是0,第二个则是1.
注意 :
序列中的最后一个元素标记为-1,倒数第二个原始为-2,以此类推.
1. 序列概览
列表和元组的主要区别在于 : 列表可以修改,元组则不能.如 : 使用元组作为字典的键,在这种情况下,因为键不能修改,所以不能用列表.
在需要操作一组数值的时候,序列很好用.可以用序列表示数据库中的一个人信息 : 第1个元素是姓名,第2个元素是年龄.根据上述内容编写一个列表(列表的各个元素通过逗号分隔,写在方括号内),如 :
|
|
同时,序列也可以包含其他的序列,因此,构建如下的一个人员信息的列表也是可以的,这个列表就是你的数据库 :
|
|
注意 :
Python之中还有一种名为容器(container)的数据结构,容器基本上是包含其他对象的任意对象.序列(例如列表和元组)和映射(例如字典)是两类主要的容器.序列中的每个元素都有自己的编号,而映射中的每个元素则有一个名字(键).既不是序列也不是映射的容器类型,集合(set)就是一个例子.
2. 通用序列操作
所有序列类型都可以进行某些特定的操作,这些操作包括 : 索引(indexing) / 分片(slicing) / 加(adding) / 乘(multiplying) 以及检查某个元素是否属于序列的成员(成员资格).
迭代(ineration) : 依次对序列中的每个元素重复执行某些操作.
2.1 索引
序列中的所有元素都是有编号的(从0开始递增).这些元素是可以通过编号来访问的.
|
|
注意 :
字符串就是一个由字符组成的序列.索引0指向第1个元素.
我们可以通过索引获取元素,所有序列都可以通过这种方式进行索引.使用负数索引时,Python会从右边,也就是最后一个元素开始计数.最后1个元素的位置编号是-1.
还有一种办法是用'hello[1]'
,结果为e
,效果是一样的.
|
|
2.2 分片
可以使用分片操作来访问一定范围内的元素,分片通过冒号隔开的两个索引来实现 :
|
|
简而言之,分片操作的实现需要提供两个索引作为边界,第1个索引的元素是包含在分片内的,而第2个则不包含在分片内.
|
|
优雅的捷径 :
假设需要访问最后的3个元素,那么可以显示的操作:numbers[7:10]
,现在,索引10指向的是11个元素,但是这个元素是不存在的,却是在最后的一个元素之后.这种做法是可行的.如果需要从列表的结尾开始计数.
实际上,只要分片中最左边的索引比它右边的晚出现在序列中,结果就是一个空序列.不过,可以使用一个捷径 : 如果分片所得部分包括序列结尾的元素,只需置空最后一个索引即可!
可以复制整个序列,可以将两个索引置空
|
|
更大的步长 :
|
|
当使用一个负数作为步长时,必须让开始点大于结束点.在没有明确指定开始点和结束点的时候,正负数的使用可能会带来些混迹.在python明确规定 : 对于正数步长,python会从序列的头部开始向右提取元素;直到最后一个元素;而对于负数步长,则是从序列的尾部开始向左提取元素,直到最后一个元素.
2.3 序列相加
|
|
两种相同的类型的序列才能连接操作.
2.4 乘法
|
|
如果想要初始化一个长度为10的空值,可以使用None
,None
是Python的一个内建值.
|
|
2.5 成员资格
为了检查一个值是否在序列中,可以使用in
运算符,这个运算符检查某个条件是否为真,然后返回相应的值.条件为真True,条件为假返回False.
|
|
|
|
2.6 长度,最小值和最大值.
len函数返回列表中所包含元素的数量,min函数和max函数则分别返回序列中最大和最小的元素.
|
|
3. 列表
列表是可变的 : 可以改变列表的内容,并且列表有很多有用的,专门的方法.
3.1 list函数
|
|
3.2 基本的列表操作
- 改变列表 : 元素赋值12341,2,3,4,5]num = [2]=22num[num[1, 2, 22, 4, 5]
注意
不能为一个位置不存在的元素进行赋值.
删除元素
从列表中删除元素用del语句来实现 :1234"kevin","shy_kevin","yujiewong"]names = [del names[1]names['kevin', 'yujiewong']分片赋值
123456'Kevin')name = list(name['K', 'e', 'v', 'i', 'n']2:]=list('ar')name[name['K', 'e', 'a', 'r']
3.3 列表方法
方法是一个与某个对象有紧密联系的函数,对象可能是列表,数字,也可能是字符串或者其他的类型的对象.一般来说,方法可以这样进行调用 :对象.方法(参数)
列表提供了几个方法,用于检查或者修改其中的内容.
append
append方法用于在列表末尾追加新的对象 :12341,2,3]lst=[4)lst.append(lst[1, 2, 3, 4]count
count方法统计某个元素在列表中出现的次数 :12345'what','be','am','is','are'].count('is')[11,2],1,1,[2,1,[1,2]]]x=[[1)x.count(2extend
extend方法可以在列表的末尾一次性追加另一个序列中的多个值.换句话说,可以用新列表扩展原有列表.123451,2,3,4,5,6]a=[1,2,3]b = [a.extend(b)a[1, 2, 3, 4, 5, 6, 1, 2, 3]
它与a+b的区别在于extend方法修改被扩展的序列,而原始的操作则不然,这是因为原始的操作创建了一个包含a和b的副本的新列表,那么连接操作的效率会比extend方法低.
- index
index方法用于从列表中找出某个值第一个匹配项的索引位置 :123'kevin','shy_kevin']names = ['kevin')names.index(0
要注意的是 : 如果搜索到的字符串不存在,会抛出异常.
- insert
insert方法用于将对象插入到列表中 :121,2,3,4,5,6,7]numbers=[3,'kevin')numbers,insert(
与extend方法一样,insert方法的操作也可以用分片赋值来实现.
- pop
pop方法会移除列表中的一个元素(默认是最后一个),并且返回该元素的值 :123456781,2,3]x = [x.pop()30)x.pop(1popx[2]
注意
pop方法是唯一一个既能修改列表又返回元素值(除了None)的列表方法.
remove
remove方法用于移除列表中的某个值的第一个匹配项 :1234'to','hello']x = ['hello')x.remove(x['to']reverse
reverse方法将列表中的元素反向存放12341,2,3]k = [k.reverse()k[3, 2, 1]sort
sort方法用于在原位置对列表进行排序.在”原位置排序”意味着改变原来的列表,从而其中的元素能按一定的顺序排列,而不是简单地返回一个已排序的列表副本.12345k[3, 2, 1]k.sort()k[1, 2, 3]高级排序
可以通过compare(x,y)的形式自定义比较函数,compare(x,y)函数会在xy时返回正数,如果x=y则返回0(根据自定义),定义好该函数后,就可以提供给sort方法作为参数.内建函数cmp提供了比较函数的默认实现方式 : 1234567891042,32)cmp(199,100)cmp(-110,10)cmp(01,2,3,4,5,6]numbers = [numbers.sort(cmp)numbers[1, 2, 3, 4, 5, 6]
sort方法有另外两个可选的参数(key和reverse),如果要使用它们,那么就要通过名字来指定(这个叫关键字参数),参数key和参数cmp类型(必须提供一个在排序过程中使用的函数).然而,该函数并不是用来确定对象的大小,而是为每个元素创建一个键,然后所有元素根据键来排序.因此,如果要根据元素的长度进行排序,那么可以使用len作为键函数.
另一个关键字reverse是简单的布尔值,用来指明列表是否要进行反向排序.
4. 元组 : 不可变序列
如果你用逗号来分隔开一些值,那么你就会自动创建了元组.
|
|
如果想要实现一个值得元组,必须加上逗号.如 : 42,
4.1 tuple函数
以一个序列作为参数并把它转换为元组.
|
|
4.2 元组的意义
- 元组可以在映射(和集合的成员)中当做键使用,而列表则不行.
- 元组作为很多内建函数和方法的返回值存在,也就是说你必须对元组进行处理.只要不尝试修改元组.那么,”处理”元组在绝大多数情况下就是把它们当做列表来进行操作.
5. 小结
函数 | 描述 |
---|---|
cmp(x,y) | 比较两个值 |
len(seq) | 返回序列的长度 |
list(seq) | 把序列转换成列表 |
max(args) | 返回列表或者参数集合中最大值 |
min(args) | 返回序列或者参数集合中的最小值 |
reversed(seq) | 把序列进行反向迭代 |
sorted(seq) | 返回已排序的包含seq所有元素的列表 |
tuple(seq) | 把序列转换成元组 |