Python 有两种循环结构。
while循环用于_不确定_(无法计数)的迭代,for循环用于_确定_(可计数)的迭代。
break、continue和else这几个关键字可以帮助你自定义循环的行为。
range()和enumerate()可以帮你进行循环计数和下标访问。
while循环只要loop expression或“测试”在boolean context中求值为True,while循环就会持续执行;一旦求值为False,循环便会终止:
# Lists are considered "truthy" in a boolean context if they
# contain one or more values, and "falsy" if they are empty.
>>> placeholders = ["spam", "ham", "eggs", "green_spam", "green_ham", "green_eggs"]
>>> while placeholders:
... print(placeholders.pop(0))
...
'spam'
'ham'
'eggs'
'green_spam'
'green_ham'
'green_eggs'
for循环Python 中基本的for loop更准确的叫法是 for each,它会依次遍历任何可迭代对象的值,当调用next()不再返回任何值时便结束:
>>> word_list = ["bird", "chicken", "barrel", "bongo"]
>>> for word in word_list:
... if word.startswith("b"):
... print(f"{word.title()} starts with a B.")
... else:
... print(f"{word.title()} doesn't start with a B.")
...
'Bird starts with a B.'
'Chicken doesn\'t start with a B.'
'Barrel starts with a B.'
'Bongo starts with a B.'
range()序列对象如果没有给定具体的iterable,就会用特殊的range()序列来充当循环计数器。
range()需要一个int来指定序列在哪里stop,还可以选择性地接收start和step形参。
如果没有提供start数字,序列就从 0 开始。
range()对象是惰性的(值按需生成),支持所有常见序列操作,而且无论指定的序列有多长,占用的内存都是固定的。
# Here we use range to produce some numbers, rather than creating a list of them in memory.
# The values will start with 1 and stop *before* 7
>>> for number in range(1, 7):
... if number % 2 == 0:
... print(f"{number} is even.")
... else:
... print(f"{number} is odd.")
'1 is odd.'
'2 is even.'
'3 is odd.'
'4 is even.'
'5 is odd.'
'6 is even.'
# range() can also take a *step* parameter.
# Here we use range to produce only the "odd" numbers, starting with 3 and stopping *before* 15.
>>> for number in range(3, 15, 2):
... if number % 2 == 0:
... print(f"{number} is even.")
... else:
... print(f"{number} is odd.")
...
'3 is odd.'
'5 is odd.'
'7 is odd.'
'9 is odd.'
'11 is odd.'
'13 is odd.'
enumerate()获取值和下标如果同时需要值和它们的下标,内置的enumerate(<iterable>)会返回 (index, value) 对:
>>> word_list = ["bird", "chicken", "barrel", "apple"]
# *index* and *word* are the loop variables.
# Loop variables can be any valid python name.
>>> for index, word in enumerate(word_list):
... if word.startswith("b"):
... print(f"{word.title()} (at index {index}) starts with a B.")
... else:
... print(f"{word.title()} (at index {index}) doesn't start with a B.")
...
'Bird (at index 0) starts with a B.'
'Chicken (at index 1) doesn\'t start with a B.'
'Barrel (at index 2) starts with a B.'
'Apple (at index 3) doesn\'t start with a B.'
# The same method can be used as a "lookup" for pairing items between two lists.
# Of course, if the lengths or indexes don't line up, this doesn't work.
>>> word_list = ["cat", "chicken", "barrel", "apple", "spinach"]
>>> category_list = ["mammal", "bird", "thing", "fruit", "vegetable"]
>>> for index, word in enumerate(word_list):
... print(f"{word.title()} is in category: {category_list[index]}.")
...
'Cat is in category: mammal.'
'Chicken is in category: bird.'
'Barrel is in category: thing.'
'Apple is in category: fruit.'
'Spinach is in category: vegetable.'
continue关键字可以用来直接跳到下一次迭代:
word_list = ["bird", "chicken", "barrel", "bongo", "sliver", "apple", "bear"]
# This will skip *bird*, at index 0
for index, word in enumerate(word_list):
if index == 0:
continue
if word.startswith("b"):
print(f"{word.title()} (at index {index}) starts with a b.")
'Barrel (at index 2) starts with a b.'
'Bongo (at index 3) starts with a b.'
'Bear (at index 6) starts with a b.'
break关键字(和许多与 C 相关的语言一样)可以用来停止迭代,并从最内层的loop中“跳出”:
>>> word_list = ["bird", "chicken", "barrel", "bongo", "sliver", "apple"]
>>> for index, word in enumerate(word_list):
... if word.startswith("b"):
... print(f"{word.title()} (at index {index}) starts with a B.")
... elif word == "sliver":
... break
... else:
... print(f"{word.title()} doesn't start with a B.")
... print("loop broken.")
...
'Bird (at index 0) starts with a B.'
'Chicken doesn\'t start with a B.'
'Barrel (at index 2) starts with a B.'
'Bongo (at index 3) starts with a B.'
'loop broken.'
你是一名助教,正在批改学生的考试试卷。 手动记录成绩既枯燥又容易出错。 你决定让这件事变得有点意思:编写几个函数,来统计和计算全班的成绩。
考试题目可以给“部分分数”,但总成绩必须是int。
所以在对全班成绩做任何处理之前,你需要先遍历这些分数,把所有float分数转成int。幸运的是,Python 内置的round()round函数正好可以用。
创建函数 round_scores(student_scores),它接收一个包含 student_scores 的 list。
这个函数应该_消耗_输入的 list,并 return 一个新的数组,其中所有分数都转换成了int。
得到的list中,分数的顺序并不重要。
>>> student_scores = [90.33, 40.5, 55.44, 70.05, 30.55, 25.45, 80.45, 95.3, 38.7, 40.3]
>>> round_scores(student_scores)
...
[40, 39, 95, 80, 25, 31, 70, 55, 40, 90]
批改试卷时,你注意到有些学生的表现没有你期望的那么好。 但你当时分了心,忘了准确记下到底有_多少_名学生不及格。
创建函数 count_failed_students(student_scores),它接收一个包含 student_scores 的 list。
这个函数应该统计出没有及格的学生人数,并以整数返回这个数字。
学生需要考到高于40的分数,才能在这门考试中及格。
>>> count_failed_students(student_scores=[90,40,55,70,30,25,80,95,38,40])
5
你协助的老师想找出在这门考试中表现“最好”的那群学生。 “最好”的标准会波动,所以你需要找出大于或等于当前阈值的那些学生分数。
创建函数 above_threshold(student_scores, threshold),以 student_scores(一个由成绩组成的 list)和 threshold(“最高分”阈值)作为形参。
这个函数应该返回一个 list,其中包含所有 >= threshold 的分数。
>>> above_threshold(student_scores=[90,40,55,70,30,68,70,75,83,96], threshold=75)
[90,75,83,96]
你协助的这位老师既喜欢给分数,也喜欢给字母等级。 因为学生很少能在考试中拿到 100 分,“字母等级”的下限是根据最高分来计算的,并在最高分与**<= 40**的不及格线之间均匀递增。
创建函数 letter_grades(highest),它以考试中的“最高”分作为实参,返回一个 list,其中包含每个“美式”等级区间的分数下限:["D", "C", "B", "A"]。
"""Where the highest score is 100, and failing is <= 40.
"F" <= 40
41 <= "D" <= 55
56 <= "C" <= 70
71 <= "B" <= 85
86 <= "A" <= 100
"""
>>> letter_grades(highest=100)
[41, 56, 71, 86]
"""Where the highest score is 88, and failing is <= 40.
"F" <= 40
41 <= "D" <= 52
53 <= "C" <= 64
65 <= "B" <= 76
77 <= "A" <= 88
"""
>>> letter_grades(highest=88)
[41, 53, 65, 77]
你有一个按降序排列的考试分数数组,还有一个学生姓名数组,也是按他们的考试分数降序排列的。 你想把每个学生的姓名和他们的考试分数对应起来,并打印出全班的总排名。
创建函数 student_ranking(student_scores, student_names),形参为 student_scores 和 student_names。
把 student_names list 中的每个学生姓名,与 student_scores list 中对应的分数配对。
你可以假定每个实参 list 都已按分数从高到低排好序。
这个函数应该返回一个由字符串组成的 list,格式为 <rank>. <student name>: <student score>。
>>> student_scores = [100, 99, 90, 84, 66, 53, 47]
>>> student_names = ['Joci', 'Sara','Kora','Jan','John','Bern', 'Fred']
>>> student_ranking(student_scores, student_names)
...
['1. Joci: 100', '2. Sara: 99', '3. Kora: 90', '4. Jan: 84', '5. John: 66', '6. Bern: 53', '7. Fred: 47']
虽然考试中拿到 100 分的“完美”成绩很罕见,但知道是否至少有一名学生做到了,还是挺有意思的。
创建函数 perfect_score(student_info),形参为 student_info。
student_info 是一个 list,其中每个数组都包含一名学生的姓名和分数:[["Charles", 90], ["Tony", 80]]。
这个函数应该 return 考试中拿到 100 分的那名学生的_第一对_ [<name>, <score>]。
如果在 student_info 中没有找到 100 分,就应该返回一个空的 list(即 [])。
>>> perfect_score(student_info=[["Charles", 90], ["Tony", 80], ["Alex", 100]])
["Alex", 100]
>>> perfect_score(student_info=[["Charles", 90], ["Tony", 80]])
[]