希望通过博客园持续的更新,分享和记录Python基础知识到高级应用的点点滴滴!
第六波:第2章 列表和元组
[总览]
数据结构,是通过某种方式组织在一起的数据元素的集合,数据元素可以使数字或字符串,甚至可以是其他数据结构。最基本的数据结构是序列sequence。
序列中的每个元素被分配一个序号---即元素的位置,也称为索引。第一个索引是0,第二个则是1,以此类推。
首先对序列作一个概览,接下来讲解对所有序列都通用的操作,而这些操作同样适用于字符串。学习如何使用列表,同时看看它有什么特别之处。然后讨论元组,元组除了不能更改之外,其他的性质和列表都很类似。
[2.1] 序列概览
Python包含6中内建的序列,重点讨论最常用的两种类型:列表和元组。其他的内建序列类型有字符串、Unicode字符串、buffer对象和xrange对象。
列表和元组的主要区别在于,列表可以修改,元组则不能。
python之中还有一种名为容器container的数据结构。容器基本上是包含其他对象的任意对象。序列和映射是两类主要的容器。序列中的每个元素都有自己的编号,而映射中的每个元组则有一个名字(也称为键)。至于既不是序列也不是映射的容器类型,集合(set)就是一个例子。
[2.2] 通用序列操作
操作:索引indexing、分片sliceing、加adding、乘multiplying以及检查某个元素是否属于序列的成员(成员资格)。还有计算序列长度、找出最大、最小元素的内建函数。
还有一个操作---迭代iteration,对序列进行迭代的意思是:一次对序列中的每个元素重复执行某些操作。
[2.2.1] 索引
序列中的所有元素都是有编号的---从零开始递增。元素可通过编号分别访问。通过索引获取元素。使用负数索引时,会从右边,也就是从最后一个元素开始计数。最后1个元素的位置编号是-1而不是0,因为那样会和第1个元素重合。
[2.2.2] 分片
分片操作来访问一定范围内的元素。分片通过冒号相隔的两个索引来实现。第1个索引是需要提取部分的第1个元素的编号,而最后的索引则是分片之后剩下部分的第1个元素的编号。简而言之,分片操作的实现需要提供两个索引作为边界,第1个索引的元素是包含在分片内的,而第2个则不包含在分片内。
1. 优雅的捷径
如果分片所得部分包括序列结尾的元素,那么只需要置空最后一个所以即可。
如果需要赋值整个序列,可以将两个索引都置空。
2. 更大的步长
分片的开始和结束点需要进行制定,而另外一个参数---步长setp length通常是隐式设置的。默认步长是1,如果步长被设置为比1大的数,那么就会跳过某些元素。步长可以是复数,即从右到做提取元素,而且必须让开始点大于结束点。
[2.2.3] 序列想家
通过使用加号可以进行序列的连接操作。两种相同类型的序列才能进行连接操作。
[2.2.4] 乘法
None、空列表和初始化
空列表可以简单地通过两个中括号进行表示,但如果想创建一个占用10个元素空间,却不包括任何内容的列表时,就需要使用None。None是一个Python的内建值,可利用None来初始化列表。
[2.2.5] 成员资格
检查一个值是否在序列中,可以使用in运算符。
[2.2.6] 长度、最小值和最大值
内建函数len、min、max。
[2.3] 列表:Python的“苦力”
列表的强大不言而喻。列表是可变的,可以改变列表的内容。
[2.3.1] list函数
因为字符串不能像列表一样被修改,所以有时根据字符串创建列表会很有用,list函数可以实现这个操作。可以用如下代码将列表转换为字符串:
''.join(somelist)
[2.3.2] 基本的列表操作
列表可以使用索引、分片、连接和乘法。列表是可以修改的。
介绍改变列表的方法:元素赋值、删除、分片赋值以及列表的方法。但注意,不是所有的列表方法都真正的改变列表。
1. 元素赋值
使用索引标记来为某个特定的、位置明确的元素赋值。不能为一个位置不存在的元素赋值。
2. 删除元素
使用del语句来实现
del list[index number]
此时删除的元素是彻底消失的。del可以用于字典元素甚至是其他变量的删除操作。
3. 分片赋值
分片赋值操作更加强大。可以使用与原序列不等长的序列将分片替换。分片赋值语句可以再不需要替换任何原有元素的情况下插入新的元素。
numbers[1:1]=[2,3,4]
这个程序只是替换了一个空的分片,因此实际的操作是插入了一个序列。以此类推,通过分片操作赋值来删除元素也是可以的。
[2.3.3] 列表方法
方法时一个与某些对象有紧密联系的函数,对象可能是列表、数字,或者字符串或者其他类型的对象。
方法可以这样进行调用:
对象.方法(参数)
对象被放置到方法名之前,并且两者之间用一个点号隔开。
1. append
append方法用于在列表末尾追加新的对象。append方法只是在恰当位置修改原来的列表,它是直接修改原来的列表。
2. count
count方法统计某个元素在列表中出现的次数。
3. extend
extend方法可以再列表的末尾一次性追加另一个序列中的多个值。即用新列表扩展原有的列表。extend方法修改了被扩展的序列,而原始的连接操作则是返回一个全新的列表。原始的连接操作创建了一个新列表。如果需要如下所示的操作,那么连接操作的效率会比extend方法低。
a=a+b
4. index
index方法用于从列表中找出某个值第一个匹配项的索引的位置。
5. insert
insert方法用于将对象插入到列表中。
6. pop
pop方法会移除列表中的一个元素,默认是最后一个,并且返回该元素的值。
pop方法是唯一一个既能修改列表又返回元素值的列表的方法。
使用pop方法可以实现一种常见的数据结构---栈。栈的原理就像堆放盘子那样,只能在顶部放一个盘子,同样也只能在顶部拿走一个盘子。最后被放入堆栈的最先被移除(这个原则称为LIFO,即后进先出)。对于上述两个栈操作,称为入栈(Push)和出栈(Pop)。Python可以使用append方法来代替入栈方法。pop方法和append方法的操作结果恰好相反。
x.append(x.pop())
如果需要实现一个先进先出(FIFO)的队列,那么可以使用insert来替代append方法。更好的解决方案是使用collection模块中的deque对象。
7. remove
remove方法用于移除列表中某个值得第一个匹配项。
8. reverse
reverse方法将列表中的元素反向存放。该方法也改变了列表但不返回值。如果需要对一个序列进行反向迭代,那么可以使用reversed函数。这个函数并不返回一个列表,而是返回一个迭代器对象。
9. sort
sort方法用于在原位置对列表进行排序。意味着改变原来的列表,从而让其中的元素能按一定的顺序排列,而不是简单地返回一个已排序的列表副本。
当用户需要一个排好序的列表副本,同时又保留原有列表不变的时候,问题就出现了。如下错误的做法:
x=[4,3,2,1,5,6]
y=x.sort()
print y # None
因为sort方法修改了x却返回了空值,那么最后得到的是已排序的x以及值为None的y。实现这个功能的正确方法是,首先把x的副本赋值给y,然后对y进行排序。如下所示:
x=[4,3,2,1,5,6]
y=x[:]
y.sort()
再次调用x[:]得到的是包含了x所有元素的分片,这是一种很有效率的赋值整个列表的方法。只是简单地把x赋值给y是没用,因为这样做就让x和y指向同一个列表了。
[2.4] 元组:不可变序列
元组不能修改。创建元组的语法很简单:如果你用逗号分隔了一些值,那么就自动创建了元组。元组中逗号是很重要的,只添加圆括号也是没用的。
[2.4.1] tuple函数
以一个序列作为参数并把它转换为元组。
[2.4.2] 基本元素操作
创建元组和访问元素。
[2.4.3] 那么,意义何在?
元组不可替代:
元组可以再映射(和集合的成员)中当作键使用;
元组作为内建函数和方法的返回值存在。
[2.5] 小结
序列:数据结构。
成员资格:in操作符检查一个值是否在容器中。
方法:方法是面向对象编程的一个重要的概念。