----用教授的方式学习
目录
4.1遍历整个列表
你经常需要遍历列表的所有元素,对每个元素执行相同的操作。
假设我们有一个魔术师名单,需要将其中每个魔术师的名字都打印出来。为此,可以分别获取名单中的每个名字,但这种做法会导致多个问题。例如,如果名单太长,将包含大量重复代码。另外,每当名单的长度发生变化时,都必须修改代码。通过使用for循环,可以让python去处理这些问题。
下面使用for循环来打印魔术师名单中的所有名字:
magicians.py
magicians=['alice','daviod','carolina'] for magician in magicians: print(magician) |
4.1.1深入研究循环
循环这种概念很重要,因为它是让计算机自动完成重复工作的常见方式之一。(略)
4.1.2 在for循环中执行更多操作
在for循环中,可对每个元素执行任何操作。下面来扩展前面的例子,对每个魔术师,都打印一条消息,指出他的表演太精彩了。
magicians.py
magicians=['alice','daviod','carolina'] for magician in magicians: print(f"{magician.title()},that was a great trick!") |
在for循环中,想包含多少行代码都可以。在代码行for magician in magicians后面,每个缩进的代码都是循环的一部分,将针对列表中的每个值都执行一次。因此,可对列表中的每个值执行任意次数的操作。
下面在添加一行代码,告诉每个魔术师,我们期待他的下一次表演:
magicians=['alice','daviod','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") |
在for循环中,想包含多少代码都可以。实际上,你会发现使用for循环对每个元素执行众多不同的操作很有用。
4.1.3 在for循环结束后执行一些操作
for循环结束后怎么办呢?通常,你需要提供总结性输出或接着执行程序必须完成的其他任务。
在for循环后面,没有缩进的代码只执行一次,不会重复执行。
4.2避免缩减错误
Python根据缩减来判断代码行与前一个代码行的关系。在前面的示例中,向各位魔术师显示的代码行是for循环的一部分,因为它们缩进了。Python通过使用缩进让代码更易读。简单地说,它要求你使用缩进让代码整洁而结构清晰。在较长的Python程序中,你将看到缩进程度各不相同的代码块,从而对程序的组织结构有大致的认识。
开始编写必须正确缩进的代码时,需要注意一些常见的缩进错误。
4.2.1 忘记缩进
对于位于for语句后面且属于循环组成部分的代码行,一定要缩进。如果忘记缩进,Python会提醒错误。
4.2.2忘记缩进额外代码
有时候,循环能够运行且不会报告错误,单结果可能出人意料。试图在循环中执行多项任务,却忘记缩进其中的一些代码时,就会出现这种情况。
这是一种逻辑错误。从语法上看,这些Python 代码是合法的,但由于逻辑错误,结果并不符合预期。如果你预期某项操作将针对每个列表元素都执行一次,但它总共只执行了一次,请确定需要将一行还是多行代码缩进。
4.2.3不必要的缩进
如果你不小心缩进了无需缩进的代码,python会指出这一点错误。
4.2.4 循环后不必要的缩进
如果不小心缩进应在循环结束后执行的代码,这写代码将针对每个列表元素重复执行。在有些情况下,这可能导致Python报告语法错误,但在大多数情况下,这只会导致逻辑错误。
4.2.5 漏掉了冒号
for语句末尾的冒号告诉Python,下一行是循环的第一行。
magicians=['alice','david','carlina'] ①for magician in magicians print(magician) |
如果不小心遗漏了冒号,如①所示,将导致语法错误,因为Python不知道你意欲何为。这种错误虽然易于消除,但并不容易发现。
4.3 创建数值列表
需要存储一组数的原因有很多。例如,在游戏中,需要跟踪每个角色的位置,还可能需要跟踪玩家的几个最高分数;在数据可视化中,处理的几乎都是由数(如温度、距离、人口数量、经度和纬度等)组成的集合。
列表非常适合存储数字集合,而Python提供了很多工具,可帮助你高效的处理列表。明白如何有效的使用这些工具后,即便列表包含数百万个元素,你编写的代码也能运行得很好。
4.3.1 使用函数range()
python函数range()让你能够轻松生成一列数。例如,可以向下面这样使用函数range()来打印一系列数:
first_numbers.py
for value in range(1,5): print(value) |
函数range()让python从指定的第一个值开始数,并在到达你指定的第二个值时停止。因为它在第二个值处停止,所以输出不包含该值(这里为5)。调用函数range()时,也可只指定一个参数,这样它将从0开始。例如,range(6)返回0~5。
4.3.2 使用range()创建数字列表
要创建数字列表,可使用函数list()将range()的结果直接转换为列表。如果将range()作为list()的参数,输出将是一个字列表。
在前一节的示例总给,只是将一系列数打印出来。要将这组数转换为列表,可使用list():
numbers=list(range(1,6)) print(numbers) |
使用函数range()时,还可指定步长。为此,可给这个函数指定第三个参数,Python将根据这个步长生成数。
例如,下面的代码打印1~10的偶数:
even_numbers.py
even_numbers=list(range(2,11,2)) print(even_numbers) |
使用range()几乎能够创建任何需要的数集。例如,如何创建一个列表,其中包含前10个整数(1~10)的平方呢?在Python中,用两个星号(**)表示乘方运算。下面的代码演示了如何将前10个整数的平方加入一个列表中:
squares.py
squares=[] for value in range(1,11): square=value**2 squares.append(square) print(squares) |
为了让代码更简洁,可不使用临时变量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.py
squares=[value**2 for vlaue in range(1,11)] print(squares) |
20这种语法,首先指定一个描述性的列表名,如squares。然后,指定一个左边括号,并定义一个表达式,用于生成要存储列表中的值。接下来,编写一个for循环,用于给表达式提供值,再加上右方括号。
4.4使用列表的一部分
处理列表的部分元素,Python称之为切片。
4.4.1 切片
要创建切片,可指定要使用的第一个元素和最后一个元素索引。与函数range()一样, Python在到达第二个索引之前的元素后停止。要输出列表中的前三个元素,需要指定索引0和3,这将返回索引为0、1和2的元素。
下面的示例处理的是一个运动队成员列表:
player.py
players=['charles','martina','michael','florence','eli'] print(players[0:3]) |
你可以生成列表的任意子集。例如,如果要提取列表的第二、第三和第四个元素,可将起始索引指定为1,并将终止索引指定为4:
players=['charles','martina','michael','florence','eli'] print(players[1:4]) |
如果没有指定第一个索引, Python将自动从列表开头开始:
players=['charles','martina','michael','florence','eli'] print(players[:4]) |
要让切片终止于列表末尾,也可使用类似的语法。例如,如果要提取从第三个元素到列表末尾的所有元素,可将起始索引指定为2,并省略终止索引:
players = ['charles', 'martina', 'michael', 'florence', 'eli'] print(players[2:]) |
无论列表多长,这种语法都能够让你输出从特定位置到列表末尾的所有元素。上一章说过,负数索引返回离列表末尾相应距离的元素,因此你可以输出列表末尾的任意切片。例如,如果要输出名单上的最后三名队员,可使用切片players[-3:]
players = ['charles', 'martina', 'michael', 'florence', 'eli'] print(players[-3:]) |
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())” |
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 = ['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 = ['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) |
4.5 元组
列表非常适合用于存储在程序运行期间可能变化的数据集。列表是可以修改的,这对处理网站的用户列表或游戏中的角色列表至关重要。然而,有时候你需要创建一系列不可修改的元素,元组可以满足这种需求。Python将不能修改的值称为不可变的 ,而不可变的列表被称为元组 。
4.5.1 定义元组
元组看起来很像列表,但使用圆括号而非中括号来标识。定义元组后,就可使用索引来访问其元素,就像访问列表元素一样。例如,如果有一个大小不应改变的矩形,可将其长度和宽度存储在一个元组中,从而确保它们是不能修改的:
dimensions.py
dimensions=(200,50) print(dimensions[0]) print(dimensions[1]) |
4.5.2遍历元组中的所有值
像列表一样,也可以使用for 循环来遍历元组中的所有值:
dimensions=(200,50) for dimension in dimensions: print(dimension) |
4.5.3 修改元组变量
虽然不能修改元组的元素,但可以给存储元组的变量赋值。因此,如果要修改前述矩形的尺寸,可重新定义整个元组:
dimensions = (200, 50) for dimension in dimensions: dimensions = (400, 100) |
4.6 设置代码格式
4.6.1缩进
PEP 8建议每级缩进都使用四个空格。这既可提高可读性,又留下了足够的多级缩进空间。
在字处理文档中,大家常常使用制表符而不是空格来缩进。对于字处理文档来说,这样做的效果很好,但混合使用制表符和空格会让Python解释器感到迷惑。每款文本编辑器都提供了一种设置,可将你输入的制表符转换为指定数量的空格。你在编写代码时绝对应该使用制表符键,但一定要对编辑器进行设置,使其在文档中插入空格而不是制表符。
在程序中混合使用制表符和空格可能导致极难排查的问题。如果混合使用了制表符和空格,可将文件中的所有制表符都转换为空格,大多数编辑器提供了这样的功能。
4.6.2 行长
很多Python程序员建议每行不超过80字符。最初制定这样的指南时,在大多数计算机中,终端窗口每行只能容纳79字符。当前,计算机屏幕每行可容纳的字符数多得多,为何还要使用79字符的标准行长呢?这里有别的原因。专业程序员通常会在同一个屏幕上打开多个文件,使用标准行长可以让他们在屏幕上并排打开两三个文件时同时看到各个文件的完整行。PEP 8还建议注释的行长不应超过72字符,因为有些工具为大型项目自动生成文档时,会在每行注释开头添加格式化字符。
PEP 8中有关行长的指南并非不可逾越的红线,有些小组将最大行长设置为99字符。在学习期间,你不用过多考虑代码的行长,但别忘了,协作编写程序时,大家几乎都遵守PEP 8指南。在大多数编辑器中,可以设置一个视觉标志(通常是一条竖线),让你知道不能越过的界线在什么地方。
4.6.3 空行
要将程序的不同部分分开,可使用空行。你应该使用空行来组织程序文件,但也不能滥用。只要按本书的示例展示的那样做,就能掌握其中的平衡。例如,如果你有五行创建列表的代码,还有三行处理该列表的代码,那么用一个空行将这两部分隔开是合适的。然而,你不应使用三四个空行将其隔开。
空行不会影响代码的运行,但会影响代码的可读性。Python解释器根据水平缩进情况来解读代码,但不关心垂直间距。
4.6.4 其他格式设置指南
PEP 8还有很多其他的格式设置建议,但这些指南针对的程序大多比目前为止本书提到的程序复杂。等介绍更复杂的Python结构时,我们再来分享相关的PEP 8指南。
------end