
3.1 列表
Python支持列表数据类型,以及丰富的列表相关功能。由于列表不需要统一数据类型,所以你可以创建不同数据类型的列表,以及多维列表。接下来的几节将展示如何在Python中操作列表结构。
3.1.1 列表和基本操作
Python列表由一对方括号括起来的逗号分隔值(comma-separated value)组成。以下示例说明了在Python中定义列表的语法,以及如何对Python列表执行各种操作:

你可以将多个变量分配给一个列表,前提是变量的数量和类型要与列表结构匹配。举个例子:

以下示例说明了如何在更复杂的数据结构中给变量赋值:

如果要获取上述代码块中date1
元素的年/月/日组成部分,可进行如下操作:

如果变量的数量和/或结构与数据不匹配,则会显示一条错误消息,如下所示:

如果指定的变量数少于数据的项数,你将看到一条错误消息,如下所示:

1. 反转和排序列表
Python的reverse()
方法可反转列表的内容,如下所示:

Python的sort()
方法可对列表进行排序:

你可以对列表进行排序,然后反转其内容,如下所示:

另一种反转列表的方法如下所示:

需要牢记的是,reversed(array)
是可迭代的,而且它并不是列表。但以下代码片段可以将一个反转的数组转换为列表:

清单3.1包含一个while
循环,其逻辑与前面介绍的列表相反:如果num
可被多个数字整除(每个数字都严格小于num
),则num
不是素数。
清单3.1 Uppercase1.py

清单3.1的输出如下所示:

排序的数字列表中,第一个数字是最小值。如果反转排序列表,则第一个数字是最大值。以下代码说明了有很多方法可以反转列表:

上述代码块的输出如下所示:

第二种(更好的)方法对列表进行排序:

第三种列表排序方法涉及sort()
方法的内置函数:

当你不想修改列表的原始顺序,或者想在一行上编写多个列表操作时,上述代码非常有用。
2. 过滤列表
Python可以过滤一个列表(也称作列表解析),如下所示:

你也可以在过滤器中指定if/else
逻辑,如下所示:

上述代码块的输出如下所示:

3. 数字和字符串的排序列表
清单3.2的Sorted1.py
脚本用于判断两个列表是否为排序列表。
清单3.2 Sorted1.py

清单3.2首先对列表list1
和list2
进行初始化,并分别基于列表list1
和list2
生成排序列表sort1
和sort2
。如果list1
等于sort1
,则list1
已被排序;同样,如果list2
等于sort2
,则list2
已被排序。
清单3.2的输出如下所示:

请注意,如果对字符串列表进行排序,输出结果是区分大小写的,大写字母出现在小写字母之前。这是因为ASCII的核对顺序把大写字母(十进制65到十进制91)放在小写字母(十进制97到十进制127)之前。下例示例可具体解释说明:

你还可以设定反转选项,用反向的顺序对列表进行排序:

你甚至可以根据列表中每一项的长度对列表进行排序:

如果想要在排序操作中将大写字母视为小写字母,可以设定str.lower
,如下所示:

4. Python中的冒泡排序
前面的示例说明了如何使用sort()
函数对数字列表进行排序。但有时需要在Python中实现其他类型的排序。清单3.3的BubbleSort.py
说明了如何在Python中实现冒泡排序。
清单3.3 BubbleSort.py

清单3.3的输出结果如下所示:

3.1.2 列表中的表达式
以下构造类似for
循环,但这个循环末尾没有冒号“:”字符:

3.1.3 连接字符串列表
Python提供了join()
方法来连接文本字符串,如下所示:

有很多方法可以连接一组字符串,然后打印结果。下面这种是效率最低的方法:

以下两种都是更佳的方法:

3.1.4 Python中的range()
函数
本节你将了解Python中可用于遍历列表的range()
函数,如下所示:

你可以使用for
循环遍历字符串列表,如下所示:

你可以使用for
循环遍历字符串列表,并显示更多详细信息,如下所示:

上面的输出结果显示列表x
中每个字符串的长度,后跟字符串文本内容。
对数字、大写和小写字母计数
清单3.4的CountCharTypes.py脚本对字符串中数字和字母进行计数。
清单3.4 Counter1.py

清单3.4初始化了与计数器相关的变量,后跟一个循环(其中循环变量设为i
),从0迭代到字符串str1
的长度。用字符串str1
索引i
位置上的字母来初始化变量char
。循环的下一部分使用条件逻辑来确定char
是数字还是字母字符。在后一种情况下(即字母字符时),代码会检查字符是大写还是小写。但不论怎样,相应的计数器变量的值都会增加。
清单3.4的输出结果如下所示:

3.1.5 数组和append()
函数
Python有一个数组类型(import array
),本质上是一个异构列表。但是除了略微节省内存使用之外,该数组类型与列表类型相比没有任何优势。你也可以定义异构数组:

你可以将新元素追加至一个列表中:

你可以将简单的变量赋值给列表中的元素,如下所示:

上述代码的输出如下所示:

Python中split()
函数比前面的示例更便捷(尤其是在元素数未知或可变的情况下),你将在下一节看到split()
函数的示例。
3.1.6 使用列表和split()
函数
你可以使用Python的split()
函数拆分文本字符串中的单词,并用这些单词填充一个列表,示例如下:

打印文本字符串中单词列表的一个简易方法如下所示:

你可以按以下方法搜索字符串中的单词:

3.1.7 对列表中的单词计数
Python提供了Counter
类,可以对列表中的单词进行计数。清单3.5的CountWord2.py
说明了如何计算出现频率最高的前三个单词。
清单3.5 CountWord2.py

清单3.5用一组字符初始化mywords
变量,然后将mywords
作为参数传递给Counter
来初始化word_counts
变量。topThree
变量是一个数组,包含了mywords
中的三个出现次数最多的字符(及其出现的次数)。清单3.5的输出如下:

3.1.8 遍历成对的列表
Python支持成对的列表操作,这意味着可以执行类似于向量的操作。以下代码片段将每个列表元素乘以3:

创建一个新列表,包含原始元素,以及原始元素乘以3的值:

计算两个列表中每对数字的乘积:

计算两个列表中每对数字的总和:

计算两个列表的每对元素的乘积:

3.1.9 其他与列表相关的函数
Python还提供了其他与列表相关的函数,例如append()
、insert()
、delete()
、pop()
和extend()
。Python中也支持index()
、count()
、sort()
和reverse()
函数。以下代码块说明了这些函数。
定义一个Python列表(允许数字重复):

显示1和2的出现次数:

在位置3处插入-8:

从例表中删除3:

从例表中删除1:

将19添加至列表:

打印列表中19的索引:

对列表进行反转:

对列表进行排序:

用列表b
扩展列表a
:

从列表中删除第一个2:

删除列表的最后一项:

现在你已经了解与列表相关的操作,下一节将介绍如何将Python列表用作栈。
3.1.10 栈和队列
栈是一种LIFO(Last In First Out,后进先出)的数据结构,其具有push()
和pop()
函数,分别用于添加和删除元素。栈中最新添加的元素位于顶部,因此是被删除的第一个元素。
以下代码说明了如何在Python中创建栈,以及从栈中删除和添加元素。创建一个Python列表(我们将其用作栈):

将5添加到栈:

从栈中删除最后一个元素:

队列是FIFO(First In First Out,先进先出)的数据结构,其具有insert()
和pop()
函数,分别用于插入和删除元素。队列中最新添加的元素位于顶部,因此是被删除的最后一个元素。将新元素添加到已满的队列时,会删除队列中最早的元素。
以下代码说明了如何在Python中创建队列,以及如何将元素插入和追加到队列中。
创建一个Python列表(我们将其用作队列):

在队列的开头插入5:

从队列中删除最后一个元素:

上面的代码使用q.insert(0,5)
在开头插入元素,并使用q.pop()
从末端删除元素。但要牢记的是,Python中insert()
操作很慢,如果在位置0执行插入,需要将基础数组中的所有元素向下复制一个位置。因此可以将collections.deque
与coll.appendleft()
、coll.pop()
一起使用,其中coll
是Collection
类的代表。
前面,你已经学习了如何利用Python列表来模拟队列。但是Python中也有一个队列对象。以下代码片段说明了如何在Python中使用队列。

下一节将介绍如何在Python中处理向量。
3.1.11 使用向量
向量是一维的数组,基于向量的操作包括加、减、内积等。清单3.6的MyVectors.py
说明了如何执行基于向量的操作。
清单3.6 MyVectors.py

清单3.6首先定义三个列表,每个列表代表一个向量。列表d1
和s1
分别表示v3
与v2
之差、v3
与v2
之和。p1
代表v3
和v2
的“内积”(也称为“点积”)。清单3.6的输出如下:

3.1.12 使用矩阵
二维矩阵即为二维数组中的值,因此创建一个矩阵是非常方便的。举个例子,下面的代码块说明了如何获得二维矩阵中的元素:

上述代码的输出结果如下:

清单3.7的My2DMatrix.py
说明了如何创建和填充二维矩阵。
清单3.7 My2DMatrix.py

清单3.7首先初始化两个变量rows
和cols
,然后用rows
x cols
得到矩阵my2DMatrix
,其初始值为0。清单3.7的下一部分包含一个嵌套循环,把位置为(row,col
)的my2DMatrix
元素赋值为row*row+col*col
。清单3.7中的最后一行代码打印了my2DArray
的内容。清单3.7的输出如下:

3.1.13 使用NumPy
库处理矩阵
NumPy
库(可以通过pip
安装)支持矩阵对象,可以处理Python中的矩阵。以下示例说明了NumPy
的一些特性。
初始化矩阵m
,然后显示其内容:

下面的代码片段返回矩阵m
的转置:

下面的代码片段返回矩阵m
的逆(如果存在):

下面的代码片段定义向量y
,然后计算乘积m*v
:

下面的代码片段导入numpy.linalg
子包,然后计算矩阵m
的行列式:

下面的代码片段查找矩阵m
的特征值:

下面的代码片段查找方程m*x=v
的解:

除了上述示例之外,NumPy
包还提供了其他功能,你可以在网上搜索相关文章和教程来了解这些功能。