第九节 列表操作2

4.3 创建数值列表

需要存储一组数的原因有很多。例如,在游戏中,需要跟踪每个角色的位置,还可 能需要跟踪玩家的几个最高得分;在数据可视化中,处理的几乎都是由数(如温度、距离、人口数量、经度和纬度等)组成的集合。

列表非常适合用于存储数字集合,而Python提供了很多工具,可帮助你高效地处理数字列表。明白如何有效地使用这些工具后,即便列表包含数百万个元素,你编写 的代码也能运行得很好。

4.3.1 使用函数range()

Python函数range() 让你能够轻松地生成一系列数。例如,可以像下面这样使用函数range() 来打印一系列数:

first_numbers.py

for value in range(1, 5): 
    print(value)

上述代码好像应该打印数1~5,但实际上不会打印5:

1 
2 
3 
4

在这个示例中,range() 只打印数1~4。这是编程语言中常见的差一行为的结果。函数range() 让Python从指定的第一个值开始数,并在到达你指定的第二个值时停止。因为它在第二个值处停止,所以输出不包含该值(这里为5)。

要打印数1~5,需要使用range(1,6) :

for value in range(1, 6): 
    print(value)

这样,输出将从1开始、到5结束:

1
2
3
4
5

使用range() 时,如果输出不符合预期,请尝试将指定的值加1或减1。

调用函数range() 时,也可只指定一个参数,这样它将从0开始。例如,range(6) 返回数0~5。

4.3.2 使用range() 创建数字列表

要创建数字列表,可使用函数list() 将range() 的结果直接转换为列表。如果将range() 作为list() 的参数,输出将是一个数字列表。

在前一节的示例中,只是将一系列数打印出来。要将这组数转换为列表,可使用list() :

numbers = list(range(1, 6)) 
    print(numbers)

结果如下:

[1, 2, 3, 4, 5]

使用函数range() 时,还可指定步长。为此,可给这个函数指定第三个参数, Python将根据这个步长来生成数。

例如,下面的代码打印1~10的偶数:

even_numbers.py

even_numbers = list(range(2, 11, 2)) 
print(even_numbers)

在这个示例中,函数range() 从2开始数,然后不断加2,直到达到或超过终值(11),因此输出如下:

[2, 4, 6, 8, 10]

使用函数range() 几乎能够创建任何需要的数集。例如,如何创建一个列表,其中包含前10个整数(1~10)的平方呢?在Python中,用两个星号(** )表示乘方运算。下面的代码演示了如何将前10个整数的平方加入一个列表中:

squares.py

squares = []❶ 
for value in range(1, 11):❷ 
    square = value ** 2❸ 
    squares.append(square)❹ 
print(squares)❺

首先,创建一个名为squares 的空列表(见❶)。接下来,使用函数range() 让Python遍历1~10的值(见❷)。在循环中,计算当前值的平方,并将结果赋给变量square (见❸)。然后,将新计算得到的平方值附加到列表squares 末尾(见❹)。最后,循环结束后,打印列表squares (见❺):

[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

为了让代码更简洁,可不使用临时变量square ,而直接将每个计算得到的值附加到列表末尾:

squares = [] for value in range(1,11): squares.append(value**2)❶ print(squares)

❶处的代码与squares.py中❸处和❹处的代码等效。在循环中,计算每个值的平方, 并立即将结果附加到列表squares 的末尾。

创建更复杂的列表时,可使用上述两种方法中的任何一种。有时候,使用临时变量会让代码更易读;而在其他情况下,这样做只会让代码无谓地变长。你首先应该考虑的是,编写清晰易懂且能完成所需功能的代码,等到审核代码时,再考虑采用更高效的方法。

4.3.3 对数字列表执行简单的统计计算

有几个专门用于处理数字列表的Python函数。例如,你可以轻松地找出数字列表的最小值、最大值和总和:

>>> digits = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0] 
>>> min(digits) 
0 
>>> max(digits) 
9 
>>> sum(digits) 
45

注意考虑到版面,本节使用的数字列表都很短,但这里介绍的知识也适用于包含数百万个数的列表。

4.3.4 列表解析

前面介绍的生成列表squares的方式包含三四行代码,而列表解析让你只需编写一行代码就能生成这样的列表。列表解析将for循环和创建新元素的代码合并成一行,并自动附加新元素。面向初学者的书并非都会介绍列表解析,这里之所以介绍列表解析,是因为等你开始阅读他人编写的代码时,很可能会遇到它。

下面的示例使用列表解析创建你在前面看到的平方数列表:

squares.py

squares = [value**2 for value in range(1, 11)] 
print(squares)

要使用这种语法,首先指定一个描述性的列表名,如squares 。然后,指定一个左方括号,并定义一个表达式,用于生成要存储到列表中的值。在这个示例中,表达  式为value**2 ,它计算平方值。接下来,编写一个for 循环,用于给表达式提供值,再加上右方括号。在这个示例中,for 循环为for value in range(1,11),它将值1~10提供给表达式value**2 。请注意,这里的for 语句末尾没有冒号。

结果与前面的平方数列表相同:

[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

要创建自己的列表解析,需要经过一定的练习,但能够熟练地创建常规列表后,你 会发现这样做是完全值得的。当你觉得编写三四行代码来生成列表有点繁复时,就 应考虑创建列表解析了。

动手试一试

练习4-3:数到20

使用一个for 循环打印数1~20(含)。

for number in range(1,21): 
    print(number)

练习4-4:一百万

创建一个包含数1~1 000 000的列表,再使用一个for 循环将这些数打印出来。(如果输出的时间太长,按Ctrl + C停止输出或关闭输出窗口。)

for number in range(1,1000001): 
    print(number)

练习4-5:一百万求和

创建一个包含数1~1 000 000的列表,再使用min() 和max()核实该列表确实是从1开始、到1 000 000结束的。另外,对这个列表调用函数sum(),看看Python将一百万个数相加需要多长时间。

numbers = [] 
for number in range(1,1000001): 
    numbers.append(number) 
print(min(numbers)) 
print(max(numbers)) 
print(sum(numbers))

练习4-6:奇数

通过给函数range()指定第三个参数来创建一个列表,其中包含1~20的奇数,再使用一个for循环将这些数打印出来。

for x in range(1,20,2): 
    print(x)

练习4-7:3的倍数

创建一个列表,其中包含3~30能被3整除的数,再使用一个for循环将这个列表中的数打印出来。

numbers = [] 
for x in range(3,31,3): 
    numbers.append(x) 
for number in numbers: 
    print(number)

练习4-8:立方  

将同一个数乘三次称为立方 。例如,在Python中,2的立方用2**3 表示。请创建一个列表,其中包含前10个整数(1~10)的立方,再使用一个for 循环将这些立方数打印出来。

numbers = [] 
for x in range(1,11): 
    numbers.append(x**3) 
for number in numbers: 
    print(number)

练习4-9:立方解析

使用列表解析生成一个列表,其中包含前10个整数的立方。

numbers = [number**3 for number in range(1,11)] 
print(numbers)

4.4 使用列表的一部分

在本章中,你一直在学习如何处理列 表的所有元素。你还可以处理列表的部分元素,Python称之为切片 。

4.4.1 切片

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

下面的示例处理的是一个运动队成员列表:

players.py

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']

无论列表多长,这种语法都能够让你输出从特定位置到列表末尾的所有元素。上一章说过,负数索引返回离列表末尾相应距离的元素,因此你可以输出列表末尾的任意切片。例如,如果要输出名单上的最后三名队员,可使用切片players[-3:] :

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

上述代码打印最后三名队员的名字,即便队员名单长度发生变化,也依然如此。

注意可在表示切片的方括号内指定第三个值。这个值告诉Python在指定范围内每隔多少元素提取一个。

4.4.2 遍历切片

如果要遍历列表的部分元素,可在for循环中使用切片。下面的示例遍历前三名队员,并打印他们的名字:

players = ['charles', 'martina', 'michael', 'florence', 'eli'] 
print("Here are the first three players on my team:") 
for player in players[:3]:❶ 
    print(player.title())

❶处的代码没有遍历整个队员列表,而只遍历前三名队员:

Here are the first three players on my team: 
Charles 
Martina 
Michael

在很多情况下,切片都很有用。例如,编写游戏时,你可以在玩家退出游戏时将其最终得分加入一个列表中,然后将该列表按降序排列以获取三个最高得分,再创建一个只包含前三个得分的切片;处理数据时,可使用切片来进行批量处理;编写Web 应用程序时,可使用切片来分页显示信息,并在每页显示数量合适的信息。

4.4.3 复制列表

我们经常需要根据既有列表创建全新的列表。下面来介绍复制列表的工作原理,以 及复制列表可提供极大帮助的一种情形。要复制列表,可创建一个包含整个列表的切片,方法是同时省略起始索引和终止索引([:] )。这让Python创建一个始于第一个元素、终止于最后一个元素的切片, 即整个列表的副本。

例如,假设有一个列表包含你最喜欢的四种食品,而你想再创建一个列表,并在其 中包含一位朋友喜欢的所有食品。不过,你喜欢的食品,这位朋友也都喜欢,因此 可通过复制来创建这个列表:

foods.py

my_foods = ['pizza', 'falafel', 'carrot cake']❶ 
friend_foods = my_foods[:]❷ 
print("My favorite foods are:") 
print(my_foods) 
print("\nMy friend's favorite foods are:") 
print(friend_foods)

首先,创建一个你喜欢的食品列表,名为my_foods (见❶)。然后创建一个名为friend_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[:]❶ 
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中(见❶)。接下来,在每个列表中都添加一种食品:在列表my_foods中添加'cannoli'(见❷),而在friend_foods中添加'ice cream'(见❸)。最后,打印这两个列表,核实这两种食品分别包含在正确的列表中。

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' 不在。如果只是将my_foods 赋给friend_foods ,就不能得到两个列表。例如,下面演示了在不使用切片的情况下复制列表的情况:

my_foods = ['pizza', 'falafel', 'carrot cake'] 
#这行不通 
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 ,而不是将my_foods 的副本赋给friend_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:切片

选择你在本章编写的一个程序,在末尾添加几行代码,以完成如下任务。

  • 打印消息“The first three items in the list are:”,再使用切片来打印列表的前三个元素。
  • 打印消息“Three items from the middle of the list are:”,再使用切片来打印列表的中间三个元素。
  • 打印消息“The last three items in the list are:”,再使用切片来打印列表的末尾三个元素。
numbers = [number**2 for number in range(1,11)] 
print(numbers) 
print("The first three items in the list are:") 
print(numbers[:3]) 
print("Three items from the middle of the list are:") 
print(numbers[4:7]) 
print("The first three items in the list are:") 
print(numbers[-3:])

练习4-11:你的比萨,我的比萨

在你为完成练习4-1而编写的程序中,创建比萨列表的副本,并将其赋给变量friend_pizzas ,再完成如下任务。

  • 在原来的比萨列表中添加一种比萨。
  • 在列表friend_pizzas 中添加另一种比萨。
  • 核实有两个不同的列表。为此,打印消息“My favorite pizzas are:”, 再使用一个for 循环来打印第一个列表;打印消息“My friend's favorite pizzas are:”,再使用一个for 循环来打印第二个列表。核实新增的比萨被添加到了正确的列表中。
my_foods = ['包子','馅饼','油条'] 
friend_foods = my_foods[:] 
my_foods.append('豆浆') 
friend_foods.append('豆腐脑') 
print('我最喜欢的食物:') 
print(my_foods) 
print('我朋友最喜欢的食物:') 
print(friend_foods)

练习4-12:使用多个循环

在本节中,为节省篇幅,程序foods.py的每个版本都没有使用for 循环来打印列表。请选择一个版本的foods.py,在其中编写两个for 循环,将各个食品列表打印出来。

my_foods = ['pizza', 'falafel', 'carrot cake'] 
for my_food in my_foods: 
    print(f"我最喜欢的食品是:{my_food}!")

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值