数据结构是以某种方式(如通过编号)组合起来的数据元素(如数、字符乃至其他数据结构)集合。在Python中,最基本的数据结构为序列(sequence)。序列中的每个元素都有编号,即其位置或索引,其中第一个元素的索引为0,第二个元素的索引为1,依此类推。在有些编程语言中,从1开始给序列中的元素编号,但从0开始指出相对于席列开头的偏移量。这显得更自然,同时可回绕到序列未尾,用负索引表示序列未尾元素的位置。序列是对列表和元组的有序数据结构的一种更高层次的抽象。
首先对序列进行概述,然后介绍一些适用于所有序列(包括列表和元组)的操作。这些操作也适用于一些示例中将使用的字符串,后面将全面介绍字符串操作。讨论这些基本知识后,将着手介绍列表,看看它们有什么特别之处,然后讨论元组。元组是一种特殊的序列,类似于列表,只是不能修改。其它编程语言似乎吗似乎没有元组这个概念。python引进元组后,很多代码都可以写得更加优雅和简洁。
列表和元组的主要不同在于,列表是可以修改的,而元组不可以。这意味着列表适用于需要中途添加元素的情形,而元组适用于出于某种考虑需要禁止修改序列的情形。禁止修改序列通常出于技术方面的考虑,与Python的内部工作原理相关,这也是有些内置函数返回元组的原因所在。在你自己编写程序时,几乎在所有情况下都可使用列表来代替元组。一种例外情况是将元组用作字典键。在这种情况下不能使用列表来代替元组,因为字典键是不允许修改的。在需要处理一系列值时,序列很有用。在数据库中,你可能使用序列来表示人,其中第一个元素为姓名,而第二个元素为年龄。如果使用列表来表示(所有元素都放在方括号内,并用逗号隔开),将类似于下面这样:
edward = ["edware gummy", 45]john = ["john smith", 42]database = [edward, john]print(database)
因为python的变量是类似于java的引用,占用的空间是固定大小的,所以列表中放不同的类型也不会引起问题。
Python支持一种数据结构的基本概念,名为容器(container)。容器基本上就是可包含其他对象的对象。两种主要的容器是序列(如列表和元组)和映射(如字典)。在序列中,每个元素都有编号,而在映射中,每个元素都有名称(也叫键)。映射将在第4章详细讨论。有一种既不是序列也不是映射的容器它就是集合(set)。有其它语言基础的同学可以进行类比记忆。
通用的序列操作
有几种操作适用于所有序列,包括索引、切片、相加、相乘和成员资格检查。另外,Python还提供了一些内置函数,可用于确定序列的长度以及找出序列中最大和最小的元素。还有一个重要的操作,它就是迭代(iteration)。对序列进行迭代意味着对其每个元素都执行特定的操作。
列表:Python的主力
列表很有用,但本节主要讨论列表不同于元组和字符串的地方列表是可变的,即可修改其内容。另外,列表有很多特有的方法。
函数list
鉴于不能像修改列表那样修改字符串,因此在有些情况下使用字符串来创建列表很有帮助。为此,可使用函数list。
list('Hello’)['h', 'e', 'l', 'l', 'o']
请注意,可将任何序列(而不仅仅是字符串)作为list的参数。
提示 要将字符列表(如前述代码中的字符列表)转换为字符串,可使用下面的表达式:
join(somelist)
其中somelist是要转换的列表。
元组:不可修改的序列
与列表一样,元组也是序列,唯一的差别在于元组是不能修改的(你可能注意到了,字符串也不能修。元组语法很简单,只要将一些值用逗号分隔,就能自动创建一个元组。
>>> 1, 2,3(1,2,3)
如你所见,元组还可用圆括号括起(这也是通常采用的做法)
>>>(1,2,3)(1.2、3)
空元组用两个不包含任何内容的圆括号表示。
>>>()
你可能会问,如何表示只包含一个值的元组呢?这有点特殊:虽然只有一个值,也必须在它后面加上逗
>>> 4242>>>42,(42,)>>>(42,)(42,)
最后两个示例创建的元组长度为1,而第一个示例根本没有创建元组。逗号至关重要,仅将值用圆括号括起不管用:(42)与42完全等效。但仅仅加上一个逗号,就能完全改变表达式的值。
>>>3*(40 + 2)126>>> 3*(40 + 2,)(42,42,42)
函数tuple的工作原理与list很像:它将一个序列作为参数,并将其转换为元组曲。如果参数已经是元组,就原封不动地返回它,
>>>tuple([1,2,3])(1,2,3)>>>tuple('abc’)('a','b','c')tuple((1,2,3)(1,2,3)
你可能意识到了,元组并不太复杂,而且除创建和访问其元素外,可对元组执行的操作不多。元组的创建及其元素的访问方式与其他序列相同,
>>> x=1,2,3>>>x[1]2>>>x[0:2](1,2)
元组的切片也是元组,就像列表的切片也是列表一样。为何要熟悉元组呢?原因有以下两个
口 它们用作映射中的键(以及集合的成员),而列表不行。
口 有些内置函数和方法返回元组,这意味着必须跟它们打交道。只要不尝试修改元组,与元组“打交道”通常意味着像处理列表一样处理它们(需要使用元组没有的index和count等方法时例外)
一般而言,使用列表足以满足对序列的需求。
小结
下面来回顾一下介绍的一些最重要的概念。
口 序列:序列是一种数据结构,其中的元素带编号(编号从0开始)。列表、字符串和元组都属于序列,其中列表是可变的(你可修改其内容),而元组和字符串是不可变的(一旦创建,内容就是固定的)。要访问序列的一部分,可使用切片操作:提供两个指定切片起始和结束位置的索引。要修改列表,可给其元素赋值,也可使用赋值语句给切片赋值。
口 成员资格:要确定特定的值是否包含在序列(或其他容器)中,可使用运算符in。将运算符in用于字符串时情况比较特殊-----这样可查找子串。
口方法:一些内置类型(如列表和字符串,但不包括元组)提供了很多有用的方法。方法有点像函数只是与特定的值相关联。方法是面向对象编程的一个重要方面。
图片1新函数总结
创建和使用字典
字典以类似于下面的方式表示:
phonebook={Alice : 2341’,'Beth':'9102','Cecil':'3258’}
字典由键及其相应的值组成,这种键-值对称为项(item)。在前面的示例中,键为名字,而值为电话号码。每个键与其值之间都用冒号(:)分隔,项之间用逗号分隔,而整个字典放在花括号内。空字典(没有任何项)用两个花括号表示,类似于下面这样:。注意 在字典(以及其他映射类型)中,键必须是独一无二的,而字典中的值无需如此。
函数dict
可使用函数dict从其他映射(如其他字典)或键-值对序列创建字典。
>>>items = [('name,Gumby'),('age’,42)]>>>d= dict(items){age:42,name:'Gumby'}>>>d [name ]Gumby
还可使用关键字实参来调用这个函数,如下所示:
>>>d= dict(name=’Gumby’, age=42)>>>d{'age’: 42,'name’: 'Gumby'}
尽管这可能是函数dict最常见的用法,但也可使用一个映射实参来调用它,这将创建一个字典,其中包含指定映射中的所有项。像函数list、tuple和str一样,如果调用这个函数时没有提供任何实参,将返回一个空字典。从映射创建字典时,如果该映射也是字典(毕竞字典是Python中唯一的内置映射类型),可不使用函数dict,而是使用字典方法copy。