【Python 学习手册笔记】列表与字典

来源:互联网 发布:喜马拉雅电台 知乎 编辑:程序博客网 时间:2024/05/17 23:05


列表与字典

Python列表是:
    任意对象的有序集合: 从功能上看,列表就是收集其他对象的地方,你可以把它们看做组。同时列表所包含的每一项都保持了从左到右的位置顺序(也就是说,它们是序列) 。
   
    通过偏移读取: 就像字符串一样,你可以通过列表对象的偏移对其进行索引,从而读取对象的某一部分内容。由于列表的每一项都是有序的,那么你也可以执行诸如分片和合并之类的任务。
   
    可变长度、异构以及任意嵌套: 与字符串不同的是,列表可以实地的增长或者缩短(长度可变) ,并且可以包含任何类型的对象而不仅仅是包含有单个字符的字符串(异构)。因为列表能够包含其他复杂的对象,又能够支持任意的嵌套,所以可以创建列表的子列表的子列表等。
   
    属于可变序列的分类:就类型分类而言,列表支持在原处的修改(它们是可变的) ,也可以响应所有针对字符串序列的操作,例如,索引、分片以及合并。实际上,序列操作在列表与字符串中的工作方式相伺。唯一的区别是:当应用于字符串上的合并和分片这样的操作应用于列表时,返回新的列表。然而列表是可变的,因此它们也支持字符串不支持的其他操作(例如,删除和索引赋值操作,它们都是在原处修改列表)。
   
    对象引用数组:从技术上来讲, Python列表包含了零个或多个其他对象的引用。列表也许会让你想起指针(地址)数组,从Python 的列表中读取一个项的速度与索引一个C语言数组差不多。实际上, 在标准Python解释器内部,列表就是C数组而不是链接结构。我们曾在第6章学过,每当用到引用时, Python总是会将这个引用指向一个对象,所以程序只需处理对象的操作。当把一个对象赋给一个数据结构元素或变量名时, Python总是会存储对象的引用,而不是对象的一个拷贝(除非明确要求保存拷贝)。
   

索引和分片的赋值都是原地修改,它们对列表进行直接修改,而不是生成一个新的列表作为结果。
>>> L = ['spam', 'Spam', 'SPAM!']
>>> L[1] = 'eggs'
>>> L
['spam', 'eggs', 'SPAM!']
>>> L[0:2] = ['eat', 'more']
>>> L
['eat', 'more', 'SPAM!']

因为这可能有点复杂,所以分片赋值最好分成两步来理解:
1. 删除。删除等号左边指定的分片。
2. 插入。将包含在等号右边对象中的片段插入旧分片被删除的位置的。
实际情况并非如此,但这有助于你理解为什么插入元素的数目不需要与删除的数目相匹配。例如,已知一个列表L的值为[1,2,3],赋值操作L[1:2 ]= [4,5] 会把L修改成列表[1, 4, 5, 3]. Python会先删除2(单项分片),然后在删除2的地方插入4和5。这也解释了为什么L[1:2]=[] 实际上是删除操作——Python删除分片(位于偏移为l 的项)之后什么也不插入。因为被赋值的序列长度不一定要与被赋值的分片的长度相匹配,所以分片赋值能够用来替换(覆盖)、增长( 插入)、缩短(删除) 主列表。

>>> L.append('please')
>>> L
['eat', 'more', 'SPAM!', 'please']
L.append(X) 与 L + [X] 的结果类似,不同的是,前者会原地修改L. 而后者会生成新的列表。

可以用del语句在原处删除某项或某片段:
>>> L
['eat', 'more', 'SPAM!', 'please']
>>> del L[0]
>>> L
['more', 'SPAM!', 'please']
>>> del L[1:]
>>> L
['more']
   
字典
除了列表以外, 字典(dictionary) 也许是Python之中最灵活的内置数据结构类型。如果把列表看做是有序的对象集合,那么就可以把字典当成是无序的集合。它们主要的差别在于: 字典当中的元素是通过键来存取的,而不是通过偏移存取。

Python字典的主要属性如下:
通过键而不是偏移量来读取: 字典有时又叫做关联数组(associative array) 或者是散列表(hash) 。它们通过键将一系列值联系起来,这样就可以使用键从字典中取出一项。就像列表那样,同样可以使用索引操作从字典中获取内容。但是索引采取键的形式,而不是相对偏移。

任意对象的无序集合: 与列表不同,保存在字典中的项并没有特定的顺序。实际上,Python将各项从左到右随机排序,以便快速查找。键提供了字典中项的象征性(而非物理性的)位置。

可变长、异构、任意嵌套:与列表相似,字典可以在原处增长或是缩短(无需生成一份拷贝)。它们可以包含任何类型的对象,而且它们支持任意深度的嵌套(可以包含列表和其他的字典等)。

属于可变映射类型:通过给索引赋值,字典可以在原处修改(可变),但不支持用于字符串和列表中的序列操作。实际上,因为字典是无序集合,所以根据固定顺序进行操作是行不通的(例如,合并和分片操作)。相反,字典是唯一内置的映射类型(键映射到值的对象)。

对象引用表(散列表):如果说列表是支持位置读取的对象引用数组,那么字典就是支持键读取的无序对象引用表。从本质上讲,字典是作为散列表(支持快速检索的数据结构)来实现的,一开始很小,并根据要求而增长。此外, Python采用最优化的散列算能来寻找键,因此搜索是很快速的。和列表一样,字典存储的是对象引用(不是拷贝)。

用于字符审和列表的in成员关系测试同样适用于字典。它能够检查某个键是否储存在字典内。

简单地给一个键赋值就可以改变或者生成元素。del 语句在这里也适用。它删除作为索引的键相关联的元素。

键不存在时通过get方法能够返回默认值(None或者用户定义的默认值);

避免missing-key错误:至少有三种方式可以让我们填入默认值而不会出现这样的错误提示:你可以在if语句中预先对键进行测试,也可以使用try语句明确地捕在并修复这一异常,还可以用我们前面介绍的get方法为不存在的键提供一个默认值:
>>> Matrix = {}
>>> Matrix[(2, 3, 4)] = 88
>>> Matrix[(7, 8, 9)] = 99
>>>
>>> Matrix
{(2, 3, 4): 88, (7, 8, 9): 99}
>>> Matrix[(2, 3, 6)]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: (2, 3, 6)
>>>
>>> if (2, 3, 6) in Matrix:
...     print(Matrix[(2, 3, 6)])
... else:
...     print(0)
...
0
>>> try:
...     print(Matrix[(2, 3, 6)])
... except KeyError:
...     print(0)
...
0
>>> Matrix.get((2, 3, 4), 0)
88
>>> Matrix.get((2, 3, 6), 0)
0

0 0
原创粉丝点击