第三章

数据结构和序列


Python的数据结构简单而强大,通晓它们才能成为熟练的Python程序员。

元组

元组是一个固定长度,不可改变的Python序列对象。

使用tuple可以将任意序列或迭代器转换成元组。

可以用方括号访问元组中的元素。和C、C++、Java等语言一样,序列是从0开始的。

元组中存储的对象可能是可变对象,一旦创建了元组,元组中的对象就不能修改了。但是当元组中包含像list这样的对象时,我们可以对list这样的元素在原位进行修改。

可以使用+将几个元组复制串联起来,得到一个新的元组。同理,将元组乘以一个整数,像列表一样,会将该元组复制整数份称为一个新的元组。

列表

与元组对比,列表的长度可变、内容可以被修改。

我们可以用方括号定义,或者使用list函数。

列表和元组的语义接近,在许多函数中可以交叉使用。

添加和删除元素

  • append在列表结尾添加元素
  • insert在特定的位置插入元素
  • pop移除并返回指定位置的元素
  • remove寻找第一个目标值并去除
  • innot in可以检查列表是否包含某个值

串联和组合列表

与元组类似,可以用+将两个列表串联起来。

如果已经定义了一个列表,用extend方法可以追加多个元素。

extend的性能要优于+

排序

我们可以使用sort函数将一个列表原地排序(而不要创建新的对象)。

二分搜索和维护已排序的列表

bisect模块支持二分查找,和向已排序的列表插入值。bisect.bisect可以找到插入值后仍保证排序的位置,bisect.insort是向这个位置插入值。

注意:bisect模块不会检查列表是否已排好序,进行检查的话会耗费大量计算。因此,对未排序的列表使用bisect不会产生错误,但结果不一定正确。

切片

用切片可以选取大多数序列类型的一部分,切片的基本形式是在方括号[]中使用[start:stop:step]

序列函数

Python有一些有用的序列函数。

enumerate函数

Python内建了一个enumerate函数,可以返回(i, value)元组序列。

1
2
for i, value in enumerate(collection):
# do something with value

sorted函数

sorted函数可以从任意序列的元素返回一个新的排好序的列表。

sorted函数可以接受和sort相同的参数。

zip函数

zip可以将多个列表、元组或其它序列成对组合成一个元组列表:

1
2
3
4
5
6
7
8
seq1 = ['foo', 'bar', 'baz']

seq2 = ['one', 'two', 'three']

zipped = zip(seq1, seq2)

list(zipped)
[('foo', 'one'), ('bar', 'two'), ('baz', 'three')]

reversed函数

reversed可以将一个序列倒序。

字典

字典是键值对的大小可变集合,键和值都是Python对象。

1
d1 = {'a' : 'some value', 'b' : [1, 2, 3, 4]}

通过key来访问字典中的value

可以用in检查列表和元组是否包含某个值的方法,检查字典中是否包含某个键。

可以用del关键字或pop方法(返回值的同时删除键)删除值。

集合

集合是无序的不可重复的元素的集合。你可以把它当做字典,但是只有键没有值。可以用两种方式创建集合:通过set函数或使用尖括号set语句:

1
2
set([2, 2, 2, 1, 3, 3])
{2, 2, 2, 1, 3, 3}

函数


如果你要重复使用相同或非常类似的代码,就需要写一个函数。通过给函数起一个名字,还可以提高代码的可读性。

函数使用def关键字声明,用return关键字返回值:

函数可以返回多个值。下面是一个简单的例子:

匿名(lambda)函数

Python支持一种被称为匿名的、或lambda函数。它仅由单条语句组成,该语句的结果就是返回值。它是通过lambda关键字定义的,这个关键字没有别的含义,仅仅是说“我们正在声明的是一个匿名函数”。

错误和异常处理

Python中使用try,except,finally来处理异常 。

文件和操作系统


为了打开一个文件以便读写,可以使用内置的open函数以及一个相对或绝对的文件路径:

1
2
path = 'examples/segismundo.txt'
f = open(path)

默认情况下,文件是以只读模式(’r’)打开的。然后,我们就可以像处理列表那样来处理这个文件句柄f了,比如对行进行迭代:
1
2
for line in f:
pass

从文件中取出的行都带有完整的行结束符(EOL),因此你常常会看到下面这样的代码(得到一组没有EOL的行):lines = [x.rstrip() for x in open(path)]

如果使用open创建文件对象,一定要用close关闭它。关闭文件可以返回操作系统资源:

1
f.close()

用with语句可以可以更容易地清理打开的文件:
1
2
with open(path) as f:
lines = [x.rstrip() for x in f]

这样可以在退出代码块时,自动关闭文件。

如果输入f =open(path,'w')就会有一个新文件被创建在path,并覆盖掉该位置原来的任何数据。另外有一个x文件模式,它可以创建可写的文件,但是如果文件路径存在,就无法创建。