Python学习记录 第四章 操作列表

第四章 操作列表

4.1 遍历整个列表

你经常需要遍历列表所有的元素,对每个元素执行相同的操作。例如,在游戏中,可能需要将每个界面元素平移相同的距离;对于包含数字的列表,可能需要对列表每个元素执行相同的统计运算。需要对列表中的每个元素执行相同的操作时,可使用Python中的for循环。

假设我们有一个魔术师名单,需要将其中每个魔术师的名字打印出来。为此,可以分别获取名单中的每个名字,但这种做法会导致多个问题。例如,名单很长,将包含大量重复的代码。另外,每当名单的长度发生变化,都必须修改代码。通过使用for循环,可以让python去处理这些问题。

下面使用for循环来打印魔术师名单中的所有名字:

magicians = ['alice','david','carolina']
for migician in magicians:
  print(migician)

首先定义了一个列表,其次定义了一个for循环。代码让python从列表magicians中取出一个名字,并将其与变量magician关联。最后让python打印前面赋给变量magician的名字。输出如下:

alice
david
carolina

4.1.1 深入研究循环

循环这种概念很重要。例如在前面使用的简单循环里,python将首先读取其中的第一行代码:

for migician in magicians:

这行代码让python获取列表magicians中的第一个值’alica’,并将其与变量magician相关联。接下来,python读取下一行代码:

  print(migician)

它让python打印magician的值,依然是’alica’。鉴于该列表还包含其它值,python返回到循环的第一行:

for migician in magicians:

Python获取列表中的下一个名字’david’,并将其与变量magician相关联,再执行下面这行代码:

  print(migician)

Python再次打印变量magician的值,当前为’david’。接下来,Python再次执行这个循环,对列表最后一个值’carolina’进行处理。至此,列表中没有其它值了,因此python接着执行程序下一行代码。在此示例中for循环后没有下一行代码,因此程序结束。

刚开始使用循环请牢记,对列表中的每个元素,都将执行循环指定的步骤,不论列表包含多少个元素。

另外,编写for循环时,可以给依次与列表中每个值相关联的临时变量指定任意名称。然而,选择描述单个列表元素的有意义名称大有裨益,例如:

for cat in cats:
for dog in dogs:
for item in list_of_items:

这些命名有助于你明白for循环中将对每个元素执行的操作。使用单复数名称帮助你判断代码处理的是单个列表元素还是多个列表元素。

4.1.2 在for循环中执行更多操作

在for循环中,可对每个元素执行任何操作。下面来扩展之前的示例,对于每位魔术师,打印一条消息:

magicians = ['alice','david','carolina']
for magician in magicians:
  print(f'{magician.title()}, that was a great trick!')

输出:

Alice, that was a great trick!
David, that was a great trick!
Carolina, that was a great trick!

在for循环中,包含多少代码都行。在代码行for magician in magicians后面,每个缩进的代码行都是循环的一部分,将针对列表中的每个值都执行一次。因此,可对列表中的每个值执行任意次数的操作。

下面再添加一行代码,告诉每位魔术师,我们期待下一次表演:

magicians = ['alice','david','carolina']
for magician in magicians:
  print(f'{magician.title()}, that was a great trick!')
  print(f"I can't wait to see your next trick,{magician.title()}.\n")

两个函数调用print( )都缩进了,因此它们都将对列表中的每位魔术师执行一次:

Alice, that was a great trick!
I can't wait to see your next trick,Alice.

David, that was a great trick!
I can't wait to see your next trick,David.

Carolina, that was a great trick!
I can't wait to see your next trick,Carolina.

4.1.3 在for循环结束后执行一些操作

for循环结束后,通常你需要提供总结性输出或接着执行程序必须完成的其它任务。

在for循环后面,没有缩进的代码都只执行一次,不会重复执行。下面打印一条向全体魔术师致谢的消息。

magicians = ['alice','david','carolina']
for magician in magicians:
    print(f"{magician.title()},that was a great trick.")
    print(f"I can't wait to see your next trick,{magician.title()}.\n")
print("Thank you,everyone.That was a great magic show!")

输出:

Alice,that was a great trick.
I can't wait to see your next trick,Alice.

David,that was a great trick.
I can't wait to see your next trick,David.

Carolina,that was a great trick.
I can't wait to see your next trick,Carolina.

Thank you,everyone.That was a great magic show!

使用for循环处理数据是一种对数据集整体操作的不错方式。例如你可能使用for循环来初始化游戏:遍历角色列表,将每个角色显示到屏幕上。然后在循环后面添加一个不缩进的代码块,在屏幕上绘制所有角色后显示一个Play Now按钮。

4.2 避免缩进错误

Python将根据缩进来判断代码行与前一个代码行的关系。在前面的示例中,向各位魔术师显示消息的代码行是for循环的一部分,因为其缩进了。Python通过使用缩进让代码更易读。它要求你使用缩进让代码整洁有序结构清晰。

开始编写必须正确缩进的代码时,需要注意一些常见的缩进错误。例如,程序员有时候会将不需要缩进的代码块缩进,而对必须缩进的代码块却忘了缩进。

下面来看一些常见的缩进错误。

4.2.1 忘记缩进

magicians = ['alice','david','carolina']
for magician in magicians:
print(f"{magician.title()},that was a great trick.")

4.2.2 忘记缩进额外的代码行

magicians = ['alice','david','carolina']
for magician in magicians:
    print(f"{magician.title()},that was a great trick.")
print(f"I can't wait to see your next trick,{magician.title()}.\n")

这是一个逻辑错误。虽然Python代码是合法的,但存在逻辑错误,结果并不符合预期。

4.2.3 不必要的缩进

如果进行了无需缩进的代码行,python会指出这一点:

message = 'Hello'
    print(message)

函数调用print( )无需缩进,因此python将指出:

 File "C:\Users\FreeDaisy\Desktop\untitled0.py", line 9
    print(message)
    ^
IndentationError: unexpected indent

为避免意外缩进错误,请只缩进需要缩进的代码。

4.2.4 循环后不必要的缩进

如果不小心缩进了应在循环结束后执行的代码,这些代码将针对每个列表元素重复执行。在少数情况下会导致python报告语法错误,但大多数情况只会导致逻辑错误。

magicians = ['alice','david','carolina']
for magician in magicians:
    print(f"{magician.title()},that was a great trick.")
    print(f"I can't wait to see your next trick,{magician.title()}.\n")
    
    print("Thank you,everyone.That was a great magic show!")

输出:

Alice,that was a great trick.
I can't wait to see your next trick,Alice.

Thank you,everyone.That was a great magic show!
David,that was a great trick.
I can't wait to see your next trick,David.

Thank you,everyone.That was a great magic show!
Carolina,that was a great trick.
I can't wait to see your next trick,Carolina.

Thank you,everyone.That was a great magic show!

4.2.5 遗漏冒号

for语句末尾的冒号告诉python,下一行是循环的第一行。

4.3 创建数值列表

列表非常适合用于存储数字集合,而python提供了很多工具,帮助你高效地处理数字列表。

4.3.1 使用函数range( )

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

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

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

1
2
3
4

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

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

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

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

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

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

输出如下:

[12345]

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

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

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

[246810]

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

squares = []
for value in range(1,11):
    square = value**2
    squares.append(square)
print(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)

输出与上述相同。

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 = [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.4 使用列表的一部分

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

4.4.1 切片

要创建切片,可指定要使用的第一个元素和最后一个元素的索引。与函数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','michael','florence']

如果没有指定第一个索引,python将从列表开头开始:

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

输出:

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

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

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

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

4.4.2 遍历切片

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

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

for player in players[:3]:
    print(player.title())

输出:

Charles
Martina
Michael

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

4.4.3 复制列表

我们经常需要根据既有的列表创建全新的列表。下面来介绍复制列表的工作原理,以及复制列表可提供极大帮助的一种情形。

要复制列表,可创建一个包含整个列表的切片,方法是同时省略起始索引和终止索引([ : ])。这让python创建一个始于第一个元素、终于最后一个元素的切片,即整个列表的副本。

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

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

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

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

打印后我们发现两个列表包含的食品相同:

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

My friend's favorite food 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 food are:")
print(friend_foods)

输出结果:

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

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

如果只是将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 food are:")
print(friend_foods)

这里将my_foods赋给friend_foods,而不是将my_foods的副本赋给friend_foods。这种语法实际上是让python将新变量friend_foods关联到已与my_foods相关联的列表,因此这两个变量指向同一个列表。

所以我们会得到这样的输出:

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

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

4.5 元组

列表非常适合用于存储在程序运行期间可能变化的数据集。列表是可以修改的,这对处理网站的用户列表或游戏中的角色列表至关重要。然而,有时你需要创建一系列不可修改的元素,元组可以满足这种要求。

Python将不能修改的值称为不可变的,而不可变的列表就称为元组。

4.5.1 定义元组

元组看起来很像列表,但使用圆括号而非中括号来标识。定义元组后,可以使用索引来访问其元素,就像访问列表元素一样。

例如,如果有一个大小不应改变的矩形,可将其长度和宽度存储在一个元组中,从而确保它们是不能修改的:

dimensions = (200,50)
print(dimensions[0])
print(dimensions[1])

首先定义了元组dimensions。为此使用了圆括号。接下来,分别打印元组的各个元素,使用的语法与访问列表元素时使用的语法相同:

200
50

下面来尝试修改元组dimensions的第一个元素,看看结果如何:

dimensions = (200,50)
dimensions[0] = 250

由于试图修改元组的操作是被禁止的,因此python指出不能给元组的元素赋值:

Traceback (most recent call last):

  File "C:\Users\FreeDaisy\Desktop\untitled0.py", line 2, in <module>
    dimensions[0] = 250

TypeError: 'tuple' object does not support item assignment

注意:严格地说,元组是由逗号标识的,圆括号只是让元组看起来更整洁、清晰。如果你要定义只包含一个元素的元组,必须在这个元素后面加上逗号:
my_t = (3,)
创建只包含一个元素的元组通常没有意义,但自动生成的元组有可能只有一个元素。

4.5.2 遍历元组中的所有值

像列表一样,也可使用for循环来遍历元组中的所有值:

dimensions = (200,50)
for dimension in dimensions:
    print(dimension)

输出:

200
50

4.5.3 修改元组变量

虽然不能修改元组的元素,但可以给存储元组的变量赋值。因此,如果要修改前述矩形的尺寸,可重新定义整个元组:

dimensions = (200,50)
print("Original dimensions:")
for dimension in dimensions:
    print(dimension)

dimensions = (400,100)
print("\nModified dimensions:")
for dimension in dimensions:
    print(dimension)

我们首先定义了一个元组并将其打印。接下来将一个新元组关联到变量dimensions,然后打印新的尺寸。这次不会报错:

Original dimensions:
200
50

Modified dimensions:
400
100

相比于列表,元组是更简单的数据结构。如果需要存储的一组值在程序的整个生命周期内都不变,就可使用元组。

4.6 设置代码格式

随着编写的程序越来越长,有必要了解一些代码格式设置约定。请花时间让你的代码易于阅读。

为确保所有人编写的代码结构都大致一致,Python程序员会遵循一些格式设置约定。

4.6.1 格式设置指南

要提出python语言修改建议,需要编写Python改进提案(Python Enhancement Proposal,PEP)。PEP 8是最古老的PEP之一,向python程序员提供了代码格式设置指南。

下面的指南可帮助你从一开始就编写清晰的代码。

4.6.2 缩进

PEP 8建议每级缩进都使用四个空格。这既可提高可读性,又留下了足够的多级缩进空间。

在字处理文档中,大家常常使用制表符而不是空格来缩进。对字处理文档来说,这样的效果很好,但混合使用制表符和空格会让python解释器感到迷惑。混合使用可能导致极难排查的问题。如果混合使用,可将文件中所有制表符转换为空格,大多数编辑器提供了这样的功能。

4.6.3 行长

PEP 8中有关行长的指南并非不可逾越的红线,在学习期间,你不用过多考虑代码的行长,但别忘了,协作编写程序时,大家几乎都遵守PEP 8指南。

4.6.4 空行

要将程序的不同部分分开,可使用空行。你应该使用空行来组织程序文件,但也不能滥用。空行不会影响代码的运行,但会影响代码的可读性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值