购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

1.5 Python中的元素集

程序通常要处理元素的集合,有时集合会非常大。我们希望方便地存储这些元素,以符合相应的目的。我们有时希望知道集合是否包含某个特定的元素,有时希望知道元素排列的顺序,有时可能还想要根据特定条件快速找到某个元素。

如你所见,与元素集进行交互的方法有很多。事实证明,选择正确的数据存储方式对于程序运行至关重要。不同的集合适用于不同的场景。什么场景应该使用什么类型的集合,是每个软件开发人员都应该掌握的一项重要技能。

Python提供了四个主要的元素集:集合、元组、列表和字典。让我们一一解释这些元素集如何存储元素以及如何使用它们。

1.5.1 集合

集合(set)中的元素唯一且无序。当我们需要快速确定元素集中是否存在某元素时,集合最有用。

Python中创建集合,可以使用set函数:

也可以使用字面量语法(literal syntax):

请注意,当使用字面量语法时,要使用大括号({})来定义集合。

我们可以使用全局函数len得到集合中元素的数量:

检查集合中是否存在元素的操作非常快速,可以使用操作符in:

使用add方法可以向集合中添加新的元素:

如果试图添加一个已经存在的元素,则什么也不会发生,因为集合中不允许存在相同的元素:

使用remove方法可以从集合中删除元素:

可以对集合使用常见的数学运算。例如,我们可以计算两个集合的差集,从而得到一个集合,其元素属于第一个集合且不属于第二个集合:

还可以计算两个集合的并集,结果是包含两个集合所有元素的集合:

可以遍历集合,但迭代的顺序是随机的:

1.5.2 元组

元组(tuple)中的元素不可变且有序。不可变(Immutable)是指元组一旦被创建,就无法更改。元组中的每个元素都有索引,从零开始递增。Python中的计数总是从零开始。

当我们在代码内部传递有序的数据集,且不希望该集合发生任何更改时,元组是很好的选择。例如,在以下代码中:

你可以放心,some_function不会以任何方式更改names元组。相比之下,如果你使用如下集合:

没有什么能阻止some_function给传递的names添加元素或从传递的names删除元素,因此你需要检查函数的代码,以确定代码是否对元素进行修改。

注意 :我们稍后将看到,无论何种情况,函数都不应该修改它们的形参 。我们在本书中编写的函数永远不会修改它们的输入形参。然而,你可能会使用其他不遵循这个规则的开发者所编写的函数,因此你需要检查这些函数是否有这类副作用。

元组使用括号来定义,内部元素以逗号分隔。如下是使用字面量语法定义的、包含我的名称和年龄的元组:

如果想创建只有一个元素的元组,我们需要在元素后面添加逗号:

创建元组也可以使用tuple函数,参数是列表格式的元素集:

使用全局函数len可以获取元组中元素的数量:

还可以使用count方法计算某元素在元组中出现的次数:

使用index方法可以得到某元素第一次出现时的索引:

在上例中,我们寻找字符串“Alvaro”的索引,“Alvaro”出现了两次:在索引1和5处。index方法会输出第一个出现的索引,在本例中即为1。

in运算符可用于检查元组中是否存在某元素:

元组可以与数字相乘,这个特殊的操作会生成一个新元组,其元素是原元组元素的重复,重复次数与乘数相同:

使用for循环可以遍历元组的元素:

使用Python内置的enumerate函数,我们可以遍历元组中的元素及其索引:

1.5.3 列表

列表(list)的元素有序但不唯一,且拥有索引。列表非常适合于元素需要有序存储且元素索引已知的场景。

列表和元组相似,唯一的区别是元组不可变,而列表中的元素可以移动,也可以增删。如果你确定一个集合中的元素不会被修改,请使用元组而非列表,因为操作元组比操作相同的列表更快。如果集合中的元素不可变,Python会进行一些优化。

创建Python列表,可以使用list函数:

或者使用字面量语法:

请注意,这里使用的是方括号([])。

使用len函数可以得到列表中元素的数量:

列表元素可以通过索引访问(第一个元素的索引为0):

我们还可以替换列表中的现有元素:

注意,不要使用列表中不存在的索引值,否则会弹出IndexError:

使用append方法可以将元素添加到列表的末尾:

通常,我们感兴趣的不仅是元素,还包括其索引。在这种情况下,我们可以使用enumerate函数,它会生成一个包含索引和元素的元组:

可以通过从其他列表中获取连续的元素来创建一个新的列表。这个过程被称为切片(slicing)。

列表切片

对列表进行切片操作,与使用方括号对列表进行索引类似,只不过我们使用的是两个用冒号分隔的索引:[<起始值>:<结束值>]。示例如下:

在上例中,我们有一个列表a:[1,2,3,4]。通过对该列表进行切片,选取从索引1(包含)到索引3(不包含)的元素,来创建一个新列表b。

注意 :请记住,Python中的切片操作总是包含起始索引的元素,不包括结束索引的元素。

图1-4描绘了这个过程。

图1-4 对列表进行切片

切片操作符中的起始值和结束值都是可选的,因为它们有默认值。默认情况下,起始索引被赋值为列表中的第一个索引,也就是0。结束索引被赋值为列表中的最后一个索引加1,等于len(the_list)。

在这个例子中,列表b_1和b_2都是列表a的副本。之所以说是副本,是因为它们确实是不同的列表,你可以放心地修改b_1或b_2,而不会改变列表a。你可以通过执行以下操作来测试这一点:

另一个小技巧是使用负索引。负索引的计数方向是从列表末尾开始,并向列表开头移动。负索引可以用于切片,操作方式和正索引相同,只有一个小的区别:负索引从-1而非-0开始。例如,我们可以对一个列表切片,得到它最后的两个值,如下:

这里我们创建了一个新的列表,从列表的倒数第二个元素开始,一直到最后一个元素。图1-5描绘了这一点。

列表切片在Python中用途广泛。

1.5.4 字典

图1-5 使用负索引对列表进行切片

字典(dictionary)是键-值对的集合。字典中的值被映射到对应的键上,我们使用键从字典中检索元素。在字典中查找值非常快速。

当我们希望存储由某些键引用的元素时,字典很有用。例如,如果我们想存储兄弟姐妹的信息,并且希望通过名称检索,那么就可以使用字典。让我们来看一下实际代码。

Python中创建字典,可以使用dict函数:

或者使用字面量语法:

dict函数需要一个元组的列表。这些元组应该包含两个值:第一个值被用作键,第二个值被用作值。创建字典的字面量语法要简洁很多,而且这两种情况生成的字典是相同的。

与列表一样,我们使用方括号访问字典中的值。不过,方括号之间是键,而不是索引:

你可以使用任何不可变对象作为字典中的键。请记住。元组不可变,列表可变。数字、字符串和布尔值也不可变,因此可以用作字典键。

让我们创建一个字典,以元组为键:

在这个例子中,年龄映射的键是由名和姓组成的元组。如果想知道Jen的年龄,我们可以用键进行检索:

当我们检索一个不在字典里的键时,会发生什么?

我们收到一个错误提示。在获取值之前,我们可以先使用in操作符,检查键是否在字典中:

如下代码可以得到字典中所有键的类集合视图:

对值也可以做同样的操作:

使用in操作符可以检查某个值是否出现在字典的键和值中:

字典可以通过几种方式进行迭代。假设我们有如下的ages字典:

我们可以使用for循环来遍历字典中的键:

对值可以做同样的操作:

也可以对键-值对做同样的操作:

以上是我们目前需要了解的Python元素集的知识。让我们继续Python之旅,看看集合的解包。 umGmklxUjnW5XyadTz0lUK6YerNZxuTDLkDO+3rompZUc4wyDGm00CP5di3QDdoL

点击中间区域
呼出菜单
上一章
目录
下一章
×