嵌入式技术
我们我们经常需要遍历列表的所有元素,对每个元素执行相同的操作。这时需要对列表中的每个元素都执行相同的操作时,可使用Python中的for 循环。
magicians = ['alice', 'david', 'carolina']
for magician in magicians:
print(magician)
alice
david
carolina
循环这种概念很重要,因为它是让计算机自动完成重复工作的常见方式之一。
使用循环时请牢记,对列表中的每个元素,都将执行循环指定的步骤,而不管列表包含多少个元素。如果列表包含一百万个元素,Python就重复执行指定的步骤一百万次,且通常速度非常快。
对于用于存储列表中每个值的临时变量,可指定任何名称。然而,选择描述单个列表元素的有意义的名称大有帮助。例如,对于小猫列表、小狗列表和一般性列表,像下面这样编写for循环的第一行代码是不错的选择:
for cat in cats:
for dog in dogs:
for item in list_of_items:
这些命名约定有助于你明白for 循环中将对每个元素执行的操作。使用单数和复数式名称,可帮助你判断代码段处理的是单个列表元素还是整个列表。
magicians = ['alice', 'david', 'carolina']
for magician in magicians:
print(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(magician.title() + ", that was a great trick!")
print("I can't wait to see your next trick, {} n".format(magician.title()))
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
在for循环后面,没有缩进的代码都只执行一次,而不会重复执行。
使用for 循环处理数据是一种对数据集执行整体操作的不错的方式。
magicians = ['alice', 'david', 'carolina']
for magician in magicians:
print(magician.title() + ", that was a great trick!")
print("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!
Python根据缩进来判断代码行与前一个代码行的关系,通过使用缩进让代码更易读;简单地说,它要求你使用缩进让代码整洁而结构清晰。在较长的Python程序中,你将看到缩进程度各不相同的代码块,这让你对程序的组织结构有大致的认识。
当你开始编写必须正确缩进的代码时,需要注意一些常见的缩进错误。
对于位于for 语句后面且属于循环组成部分的代码行,一定要缩进。如果你忘记缩进,Python会提醒你应缩进却没有缩进。Python没有找到期望缩进的代码块时,会让你知道哪行代码有问题。
magicians = ['alice', 'david', 'carolina']
for magician in magicians:
print(magician)
File "< ipython-input-5-bc3e0c643e2b >", line 3
print(magician)
^
IndentationError: expected an indented block
有时候,循环能够运行而不会报告错误,但结果可能会出乎意料。试图在循环中执行多项任务,却忘记缩进其中的一些代码行时,就会出现这种情况。
这时产生的是逻辑错误 。从语法上看,这些Python代码是合法的,但由于存在逻辑错误,结果并不符合预期。如果预期某项操作将针对每个列表元素都执行一次,但它却只执行了一次,请确定是否需要将一行或多行代码缩进。
#注意循环中缩进的影响
magicians = ['alice', 'david', 'carolina']
for magician in magicians:
print(magician.title() + ", that was a great trick!")
print("I can't wait to see your next trick, {}n".format(magician.title()))
Alice, that was a great trick!
David, that was a great trick!
Carolina, that was a great trick!
I can't wait to see your next trick, Carolina
如果你不小心缩进了无需缩进的代码行,Python将指出无需缩进,因为它并不属于前一行代码。
message = "Hello Python world!"
print(message)
File "< ipython-input-7-e744c47c5d20 >", line 2
print(message)
^
IndentationError: unexpected indent
如果你缩进了应在循环结束后执行的代码,这些代码将针对每个列表元素重复执行。在有些情况下,这可能导致Python报告语法错误,但在大多数情况下,这只会导致逻辑错误。
magicians = ['alice', 'david', 'carolina']
for magician in magicians:
print(magician.title() + ", that was a great trick!")
print("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!
for 语句末尾的冒号告诉Python,下一行是循环的第一行。如果遗漏了冒号,将导致语法错误,因为Python不知道你意欲何为。
magicians = ['alice', 'david', 'carolina']
for magician in magicians
print(magician)
File "< ipython-input-9-0b84a6ab73bd >", line 2
for magician in magicians
^
SyntaxError: invalid syntax
练习: 4-1 比萨 :想出至少三种你喜欢的比萨,将其名称存储在一个列表中,再使用for 循环将每种比萨的名称都打印出来。
修改这个for 循环,使其打印包含比萨名称的句子,而不仅仅是比萨的名称。对于每种比萨,都显示一行输出,如“I like pepperoni pizza”。
在程序末尾添加一行代码,它不在for 循环中,指出你有多喜欢比萨。输出应包含针对每种比萨的消息,还有一个总结性句子,如“I really love pizza!”。
4-2 动物 :想出至少三种有共同特征的动物,将这些动物的名称存储在一个列表中,再使用for 循环将每种动物的名称都打印出来。
修改这个程序,使其针对每种动物都打印一个句子,如“A dog would make a great pet”。
在程序末尾添加一行代码,指出这些动物的共同之处,如打印诸如“Any of these animals would make a great pet!”这样的句子。
# 4-1 不知道有些什么口味的pizza,乱来
print("----------------------")
pizzas = ['pepperoni', 'chicken', 'pork']
for pizza in pizzas:
print("I like {} pizza.".format(pizza))
print("I really love pizza!")
# 4-2
print("-----------------------")
pets = ['dog', 'cat', 'lizard']
for pet in pets:
print("A {} would make a great pet.".format(pet))
print("Any of these animals would make a great pet!")
----------------------
I like pepperoni pizza.
I like chicken pizza.
I like pork pizza.
I really love pizza!
-----------------------
A dog would make a great pet.
A cat would make a great pet.
A lizard would make a great pet.
Any of these animals would make a great pet!
列表非常适合用于存储数字集合,而Python提供了很多工具
下例中range()只是打印数字1~4,这是经常看到的差一行为的结果。如果要打印出1~5,我更喜欢下面的方式。
for value in range(1,5):
print(value)
1
2
3
4
for value in range(5):
print(value+1)
1
2
3
4
5
要创建数字列表,可使用函数list()将range() 的结果直接转换为列表。如果将range()作为list()的参数,输出将为一个数字列表。
使用函数range() 时,还可指定步长。第二段代码打印1~10内的偶数。
numbers = list(range(1,6))
print(numbers)
[1, 2, 3, 4, 5]
even_numbers = list(range(2,11,2))
print(even_numbers)
[2, 4, 6, 8, 10]
使用函数range() 几乎能够创建任何需要的数字集,例如,创建一个列表,其中包含前10个整数(即1~10)的平方:
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]
#更简洁的一种方法
squares = []
for value in range(1,11):
squares.append(value**2)
print(squares)
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
创建更复杂的列表时,可使用上述两种方法中的任何一种。有时候,使用临时变量会让代码更易读;而在其他情况下,这样做只会让代码无谓地变长。
首先应该考虑的是,编写清晰易懂且能完成所需功能的代码;等到审核代码时,再考虑采用更高效的方法。
回想一下之前的python之禅(zen of python)。
有几个专门用于处理数字列表的Python函数。例如,找出数字列表的最大值、最小值和总和。
#更复杂、专业的统计可以通过numpy和pandas库来实现。
digits = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
print(min(digits))
print(max(digits))
print(sum(digits))
0
9
45
使用列表解析创建你在前面看到的平方数列表。使用这种语法,首先指定一个描述性的列表名,如squares;然后,指定一个左方括号,并定义一个表达式,用于生成你要存储到列表中的值。在这个示例中,表达式为 ,它计算平方值。接下来,编写一个for循环,用于给表达式提供值,再加上右方括号。在这个示例中,for 循环为for value in range(1,11) ,它将值1~10提供给表达式。
这里的for 语句末尾没有冒号。
squares = [value**2for value in range(1,11)]
print(squares)
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
练习: 4-3 数到20 :使用一个for 循环打印数字1~20(含)。
4-4 一百万 :创建一个列表,其中包含数字1~1 000 000,再使用一个for 循环将这些数字打印出来(如果输出的时间太长,按Ctrl + C停止输出,或关闭输出窗口)。
4-5 计算11 000 000的总和 :创建一个列表,其中包含数字11 000 000,再使用min() 和max() 核实该列表确实是从1开始,到1 000 000结束的。另外,对这个列表调用函数sum() ,看看Python将一百万个数字相加需要多长时间。
4-6 奇数 :通过给函数range() 指定第三个参数来创建一个列表,其中包含1~20的奇数;再使用一个for 循环将这些数字都打印出来。
4-7 3的倍数 :创建一个列表,其中包含3~30内能被3整除的数字;再使用一个for 循环将这个列表中的数字都打印出来。
4-8 立方 :将同一个数字乘三次称为立方。例如,在Python中,2的立方用 表示。请创建一个列表,其中包含前10个整数(即1~10)的立方,再使用一个for 循环将这些立方数都打印出来。
4-9 立方解析 :使用列表解析生成一个列表,其中包含前10个整数的立方。
%time
# 4-3
print("-----4-3-----")
for value in range(1,21):
print(value,end='t')
print("n")
# 4-4
print("-----4-4-----")
values = list(range(1,101))
for value in values:
print(value,end='t')
print("n")
# 4-5
print("-----4-5-----")
values = list(range(1,1000001))
print(min(values),max(values))
print(sum(values))
# 4-6
print("-----4-6-----")
for odd in range(1,21,2):
print(odd,end='t')
print("n")
# 4-7
print("-----4-7-----")
for value in range(3,31,3):
print(value,end='t')
print("n")
# 4-8
print("-----4-8-----")
cubics = [value**3for value in range(1,11)]
for cubic in cubics:
print(cubic,end='t')
print("n")
# 4-9
print("-----4-9-----")
cubics = [value**3for value in range(1,11)]
print(cubics)
CPU times: user 7 µs, sys: 1 µs, total: 8 µs
Wall time: 15 µs
-----4-3-----
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
-----4-4-----
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
-----4-5-----
1 1000000
500000500000
-----4-6-----
1 3 5 7 9 11 13 15 17 19
-----4-7-----
3 6 9 12 15 18 21 24 27 30
-----4-8-----
1 8 27 64 125 216 343 512 729 1000
-----4-9-----
[1, 8, 27, 64, 125, 216, 343, 512, 729, 1000]
除了处理列表的所有元素,还可以处理列表的部分元素——Python称之为切片 。
要创建切片,可指定要使用的第一个元素和最后一个元素的索引。与函数range() 一样,Python在到达你指定的第二个索引前面的元素后停止。要输出列表中的前三个元素,需要指定索引0~3,这将输出分别为0 、1 和2 的元素。
- 使用[]进行切片操作;
- 如果没有指定第一个索引,Python将自动从列表开头开始;
- 如果要让切片终止于列表末尾,也可使用类似的语法;
- 负数索引返回离列表末尾相应距离的元素,因此你可以输出列表末尾的任何切片。
players = ['charles', 'martina', 'michael', 'florence', 'eli']
print(players[0:3])
print(players[1:4])
print(players[:2])
print(players[3:])
print(players[-3:])
['charles', 'martina', 'michael']
['martina', 'michael', 'florence']
['charles', 'martina']
['florence', 'eli']
['michael', 'florence', 'eli']
如果要遍历列表的部分元素,可在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
要复制列表,可创建一个包含整个列表的切片,方法是同时省略起始索引和终止索引([:] )。这让Python创建一个始于第一个元素,终止于最后一个元素的切片,即复制整个列表。
注意:这里与直接赋值不同,直接赋值类似于指针,指向的是同一段内存地址。
my_foods = ['pizza', 'falafel', 'carrot cake']
friend_foods = my_foods[:]
print("My favorite foods are:")
print(my_foods)
print("My friend's favorite foods are:")
print(friend_foods)
My favorite foods are:
['pizza', 'falafel', 'carrot cake']
My friend's favorite foods are:
['pizza', 'falafel', 'carrot cake']
#这里的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("My friend's favorite foods are:")
print(friend_foods)
My favorite foods are:
['pizza', 'falafel', 'carrot cake', 'cannoli']
My friend's favorite foods are:
['pizza', 'falafel', 'carrot cake', 'ice cream']
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("My friend's favorite foods are:")
print(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:”,再使用切片来打印列表末尾的三个元素。
4-11 你的比萨和我的比萨 :在你为完成练习4-1而编写的程序中,创建比萨列表的副本,并将其存储到变量friend_pizzas 中,再完成如下任务。
在原来的比萨列表中添加一种比萨。
在列表friend_pizzas 中添加另一种比萨。
核实你有两个不同的列表。为此,打印消息“My favorite pizzas are:”,再使用一个for 循环来打印第一个列表;打印消息“My friend's favorite pizzas are:”,再使用一个for 循环来打印第二个列表。核实新增的比萨被添加到了正确的列表中。
4-12 使用多个循环 :在本节中,为节省篇幅,程序foods.py的每个版本都没有使用for 循环来打印列表。请选择一个版本的foods.py,在其中编写两个for 循环,将各个食品列表都打印出来。
# 4-10
print("-----4-10-----")
players = ['charles', 'martina', 'michael', 'florence', 'eli']
print("The first three items in the list are: {}".format(players[:3]))
print("Three items from the middle of the list are: {}".format(players[int(len(players)/2)-1:int(len(players)/2)+2]))
print("The last three items in the list are: {}".format(players[-3:]))
# 4-11
print("-----4-11-----")
my_pizzas = ['pepperoni', 'chicken', 'pork']
friend_pizzas = my_pizzas[:]
my_pizzas.append('beacon')
friend_pizzas.append('cheese')
print("My favorite pizzas are: {}".format(my_pizzas))
print("My friend's favorite pizzas are: {}".format(friend_pizzas))
# 4-12
print("-----4-12-----")
for pizza in my_pizzas:
print(pizza,end='t')
-----4-10-----
The first three items in the list are: ['charles', 'martina', 'michael']
Three items from the middle of the list are: ['martina', 'michael', 'florence']
The last three items in the list are: ['michael', 'florence', 'eli']
-----4-11-----
My favorite pizzas are: ['pepperoni', 'chicken', 'pork', 'beacon']
My friend's favorite pizzas are: ['pepperoni', 'chicken', 'pork', 'cheese']
-----4-12-----
pepperoni chicken pork beacon
列表是可以修改的,然而,有时候需要创建一系列不可修改的元素,元组可以满足这种需求。
Python将不能修改的值称为不可变的,而不可变的列表被称为元组
。
元组看起来犹如列表,但使用圆括号()
而不是方括号来标识。定义元组后,就可以使用索引来访问其元素,就像访问列表元素一样。
dimensions = (200, 50)
print(dimensions[0])
print(dimensions[1])
200
50
#尝试修改内容,将会报错
dimensions = (200, 50)
dimensions[0] = 250
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
< ipython-input-27-8d3115351a22 > in < module >()
1 #尝试修改内容,将会报错
2 dimensions = (200, 50)
---- > 3 dimensions[0] = 250
TypeError: 'tuple' object does not support item assignment
和列表一样,也可以使用for 循环来遍历元组中的所有值。
dimensions = (200, 50)
for dimension in dimensions:
print(dimension)
200
50
虽然不能修改元组的元素,但可以给储元组的变量赋值。因此,如果要修改前述变量的大小,可重新定义整个元组。
相比于列表,元组是更简单的数据结构。如果需要存储的一组值在程序的整个生命周期内都不变,可使用元组。
dimensions = (200, 50)
print("Original dimensions:")
for dimension in dimensions:
print(dimension)
dimensions = (400, 100, 20)
print("Modified dimensions:")
for dimension in dimensions:
print(dimension)
Original dimensions:
200
50
Modified dimensions:
400
100
20
练习: 4-13 自助餐 :有一家自助式餐馆,只提供五种简单的食品。请想出五种简单的食品,并将其存储在一个元组中。
使用一个for 循环将该餐馆提供的五种食品都打印出来。
尝试修改其中的一个元素,核实Python确实会拒绝你这样做。
餐馆调整了菜单,替换了它提供的其中两种食品。请编写一个这样的代码块:给元组变量赋值,并使用一个for 循环将新元组的每个元素都打印出来。
# 4-13
print("-----4-13-----")
foods = ('milk', 'cola', 'coffee', 'egg', 'noodles')
for food in foods:
print(food, end="t")
print("n")
foods = ('water', 'cola', 'tea', 'egg', 'noodles')
for food in foods:
print(food, end="t")
foods[0]='cake'
-----4-13-----
milk cola coffee egg noodles
water cola tea egg noodles
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
< ipython-input-30-445179e5af1a > in < module >()
8 for food in foods:
9 print(food, end="t")
--- > 10 foods[0]='cake'
TypeError: 'tuple' object does not support item assignment
随着程序越来越长,有必要了解一些代码格式设置约定。花时间让代码尽可能易于阅读;让代码易于阅读有助于你掌握程序是做什么的,也可以帮助他人理解你编写的代码。
为确保所有人编写的代码的结构都大致一致,Python程序员都遵循一些格式设置约定。学会编写整洁的Python后,就能明白他人编写的Python代码的整体结构——只要他们和你遵循相同的指南。要成为专业程序员,应从现在开始就遵循这些指南,以养成良好的习惯。
若要提出Python语言修改建议,需要编写Python改进提案(Python Enhancement Proposal,PEP)。PEP 8是最古老的PEP之一,它向Python程序员提供了代码格式设置指南。PEP 8的篇幅很长,但大都与复杂的编码结构相关。
Python格式设置指南的编写者深知,代码被阅读的次数比编写的次数多。代码编写出来后,调试时你需要阅读它;给程序添加新功能时,需要花很长的时间阅读代码;与其他程序员分享代码时,这些程序员也将阅读它们。
如果一定要在让代码易于编写和易于阅读之间做出选择,Python程序员几乎总是会选择后者。下面的指南可帮助你从一开始就编写出清晰的代码。
PEP 8建议每级缩进都使用四个空格,这既可提高可读性,又留下了足够的多级缩进空间。
在字处理文档中,大家常常使用制表符而不是空格来缩进。对于字处理文档来说,这样做的效果很好,但混合使用制表符和空格会让Python解释器感到迷惑。每款文本编辑器都提供了一种设置,可将输入的制表符转换为指定数量的空格。在编写代码时应该使用制表符键,但一定要对编辑器进行设置,使其在文档中插入空格而不是制表符。
在程序中混合使用制表符和空格可能导致极难解决的问题。如果你混合使用了制表符和空格,可将文件中所有的制表符转换为空格,大多数编辑器都提供了这样的功能。
很多Python程序员都建议每行不超过80字符。最初制定这样的指南时,在大多数计算机中,终端窗口每行只能容纳79字符;当前,计算机屏幕每行可容纳的字符数多得多,为何还要使用79字符的标准行长呢?这里有别的原因。专业程序员通常会在同一个屏幕上打开多个文件,使用标准行长可以让他们在屏幕上并排打开两三个文件时能同时看到各个文件的完整行。PEP 8还建议注释的行长都不超过72字符,因为有些工具为大型项目自动生成文档时,会在每行注释开头添加格式化字符。
PEP 8中有关行长的指南并非不可逾越的红线,有些小组将最大行长设置为99字符。在学习期间,你不用过多地考虑代码的行长,但别忘了,协作编写程序时,大家几乎都遵守PEP 8指南。在大多数编辑器中,都可设置一个视觉标志——通常是一条竖线,让你知道不能越过的界线在什么地方。
附录B介绍了如何配置文本编辑器,以使其:在你按制表符键时插入四个空格;显示一条垂直参考线,帮助你遵守行长不能超过79字符的约定。
要将程序的不同部分分开,可使用空行。你应该使用空行来组织程序文件,但也不能滥用。
空行不会影响代码的运行,但会影响代码的可读性。Python解释器根据水平缩进情况来解读代码,但不关心垂直间距。
PEP 8还有很多其他的格式设置建议,但这些指南针对的程序大都比目前为止本书提到的程序复杂。等介绍更复杂的Python结构时,我们再来分享相关的PEP 8指南。
练习: 4-14 PEP 8 :请访问https://python.org/dev/peps/pep-0008/ ,阅读PEP 8格式设置指南。当前,这些指南适用的不多,但你可以大致浏览一下。
全部0条评论
快来发表一下你的评论吧 !