使用列表的一部分

在第 3 章中,您学习了如何访问列表中的单个元素,而在本章中,您学习了如何访问列表中的所有元素。 您还可以处理列表中的一组特定项目,在 Python 中称为切片。

切片

要制作切片,您需要指定要使用的第一个和最后一个元素的索引。 与 range() 函数一样,Python 在您指定的第二个索引之前停止一项。 要输出列表中的前三个元素,您可以请求索引 0 到 3,这将返回元素 0、1 和 2。

以下示例涉及一个团队中的球员列表:

players = ['charles', 'martina', 'michael', 'florence', 'eli']
print(players[0:3])

此代码打印列表的一部分。 输出保留列表的结构,并包括列表中的前三个玩家:

['charles', 'martina', 'michael']

您可以生成列表的任何子集。 例如,如果您想要列表中的第二个、第三个和第四个项目,您将在索引 1 处开始切片并在索引 4 处结束它:

players = ['charles', 'martina', 'michael', 'florence', 'eli']
print(players[1:4])

这次切片以 "martina" 开始,以 "florence" 结束:

['martina', 'michael', 'florence']

如果省略切片中的第一个索引,Python 会自动在列表的开头启动切片:

players = ['charles', 'martina', 'michael', 'florence', 'eli']
print(players[:4])

没有起始索引,Python 从列表的开头开始:

['charles', 'martina', 'michael', 'florence']

如果您想要一个包含列表末尾的切片,则可以使用类似的语法。 例如,如果您想要从第三个项目到最后一个项目的所有项目,您可以从索引 2 开始并省略第二个索引:

players = ['charles', 'martina', 'michael', 'florence', 'eli']
print(players[2:])

Python 返回从第三个项目到列表末尾的所有项目:

['michael', 'florence', 'eli']

此语法允许您输出从列表中的任意点到末尾的所有元素,而不管列表的长度如何。 回想一下,负索引返回距列表末尾一定距离的元素; 因此,您可以输出列表末尾的任何切片。 例如,如果我们想输出名单上的最后三名球员,我们可以使用 slice players[-3:]

players = ['charles', 'martina', 'michael', 'florence', 'eli']
print(players[-3:])

这将打印出最后三名玩家的名字,并将随着玩家列表大小的变化而继续工作。

您可以在表示切片的括号中包含第三个值。 如果包含第三个值,这会告诉 Python 在指定范围内的项目之间跳过多少项目。

遍历切片

如果要遍历列表中元素的子集,可以在 for 循环中使用切片。 在下一个示例中,我们遍历前三名球员并将他们的名字作为简单花名册的一部分打印出来:

players = ['charles', 'martina', 'michael', 'florence', 'eli']

print("Here are the first three players on my team:")
for player in players[:3]: (1)
    print(player.title())
1 Python 不是遍历整个玩家列表,而是只遍历前三个名字:
Here are the first three players on my team:
Charles
Martina
Michael

切片在许多情况下都非常有用。 例如,当您创建游戏时,您可以在玩家每次结束游戏时将其最终得分添加到列表中。 然后,您可以通过按降序对列表进行排序并获取仅包含前三个分数的切片来获得玩家的前三个分数。 当您处理数据时,您可以使用切片以特定大小的块来处理数据。 或者,当您构建 Web 应用程序时,您可以使用切片在一系列页面中显示信息,并在每个页面上显示适当数量的信息。

复制列表

通常,您会希望从现有列表开始,然后在第一个列表的基础上制作一个全新的列表。 让我们探讨复制列表的工作原理,并检查一种复制列表有用的情况。 要复制列表,您可以通过省略第一个索引和第二个索引 ([:]) 来制作包含整个原始列表的切片。 这告诉 Python 制作一个从第一项开始到最后一项结束的切片,从而生成整个列表的副本。 例如,假设我们有一个我们最喜欢的食物的列表,并且想要单独列出一个朋友喜欢的食物。 到目前为止,这位朋友喜欢我们列表中的所有内容,因此我们可以通过复制我们的列表来创建他们的列表:

my_foods = ['pizza', 'falafel', 'carrot cake']
friend_foods = my_foods[:] (1)

print("My favorite foods are:")
print(my_foods)

print("\nMy friend's favorite foods are:")
print(friend_foods)
1 首先,我们列出我们喜欢的食物,称为 my_foods。 然后我们创建一个名为 friend_foods 的新列表。 我们通过在不指定任何索引的情况下请求 my_foods 的一片来制作 my_foods 的副本,并将副本分配给 friend_foods。 当我们打印每个列表时,我们看到它们都包含相同的食物:
My favorite foods are:
['pizza', 'falafel', 'carrot cake']

My friend's favorite foods are:
['pizza', 'falafel', 'carrot cake']

为了证明我们实际上有两个单独的列表,我们将向每个列表添加一种新食物,并显示每个列表都会跟踪相应的人最喜欢的食物:

my_foods = ['pizza', 'falafel', 'carrot cake']
friend_foods = my_foods[:] (1)

my_foods.append('cannoli') (2)
friend_foods.append('ice cream') (3)

print("My favorite foods are:")
print(my_foods)

print("\nMy friend's favorite foods are:")
print(friend_foods)
1 我们将 my_foods 中的原始项目复制到新列表 friend_foods 中,就像我们在前面的示例中所做的那样。
2 接下来,我们向每个列表添加一种新食物:我们将 "cannoli" 添加到 my_foods ,
3 并将 "ice cream" 添加到 friend_foods 。 然后我们打印这两个列表以查看这些食物中的每一个是否在适当的列表中:
My favorite foods are:
['pizza', 'falafel', 'carrot cake', 'cannoli']

My friend's favorite foods are:
['pizza', 'falafel', 'carrot cake', 'ice cream']

输出显示 “cannoli” 现在出现在我们最喜欢的食物列表中,但 “ice cream” 没有出现。 我们可以看到 “ice cream” 现在出现在我们朋友的列表中,但 “cannoli” 没有。 如果我们简单地设置 friend_foods 等于 my_foods,我们就不会产生两个单独的列表。 例如,当您尝试在不使用切片的情况下复制列表时会发生以下情况:

my_foods = ['pizza', 'falafel', 'carrot cake']

# This doesn't work:
friend_foods = my_foods

my_foods.append('cannoli')
friend_foods.append('ice cream')

print("My favorite foods are:")
print(my_foods)

print("\nMy friend's favorite foods are:")
print(friend_foods)

我们没有将 my_foods 的副本分配给 friend_foods,而是将 friend_foods 设置为等于 my_foods。 此语法实际上告诉 Python 将新变量 friend_foods 与已经与 my_foods 关联的列表相关联,因此现在这两个变量都指向同一个列表。 因此,当我们将 “cannoli” 添加到 my_foods 时,它也会出现在 friend_foods 中。 同样,'ice cream' 将出现在两个列表中,即使它似乎只被添加到 friend_foods。

输出显示两个列表现在相同,这不是我们想要的:

My favorite foods are:
['pizza', 'falafel', 'carrot cake', 'cannoli', 'ice cream']

My friend's favorite foods are:
['pizza', 'falafel', 'carrot cake', 'cannoli', 'ice cream']

现在不要担心这个例子中的细节。 如果您尝试使用列表的副本并看到意外行为,请确保您正在使用切片复制列表,就像我们在第一个示例中所做的那样。

自己试试
4-10.Slices

使用您在本章中编写的一个程序,在程序末尾添加几行,执行以下操作: 打印消息 列表中的前三项是:。 然后使用切片打印该程序列表中的前三项。 打印消息 列表中间的三项是:。 然后使用切片打印列表中间的三个项目。 打印消息 列表中的最后三项是:。 然后使用切片打印列表中的最后三个项目。

4-11.My Pizzas,Your Pizzas

从练习 4-1(第 56 页)中的程序开始。 复制一份披萨列表,并将其命名为 friend_pizzas。 然后,执行以下操作: 向原始列表中添加一个新的比萨饼。 将不同的披萨添加到列表 friend_pizzas。 证明您有两个单独的列表。 打印消息 My favorite pizzas are:,然后使用 for 循环打印第一个列表。 打印消息 My friend’s favorite pizzas are:,然后使用 for 循环打印第二个列表。 确保每个新披萨都存储在适当的列表中。

4-12.More Loops

本节中所有版本的 foods.py 都避免在打印时使用 for 循环,以节省空间。 选择一个版本的 foods.py,并编写两个 for 循环来打印每个食物列表。