轨道
/
Python
Python
/
练习
/
成绩评定
成绩评定

成绩评定

学习练习

简介

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

说明

你是一名助教,正在批改学生的考试试卷。 手动记录成绩既枯燥又容易出错。 你决定让这件事变得有点意思:编写几个函数,来统计和计算全班的成绩。

1. 分数取整

考试题目可以给“部分分数”,但总成绩必须是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]

2. 不及格的学生

批改试卷时,你注意到有些学生的表现没有你期望的那么好。 但你当时分了心,忘了准确记下到底有_多少_名学生不及格。

创建函数 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

3. “最好”的成绩

你协助的老师想找出在这门考试中表现“最好”的那群学生。 “最好”的标准会波动,所以你需要找出大于或等于当前阈值的那些学生分数。

创建函数 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]

4. 计算字母等级

你协助的这位老师既喜欢给分数,也喜欢给字母等级。 因为学生很少能在考试中拿到 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]

5. 把姓名与分数配对

你有一个按降序排列的考试分数数组,还有一个学生姓名数组,也是按他们的考试分数降序排列的。 你想把每个学生的姓名和他们的考试分数对应起来,并打印出全班的总排名。

创建函数 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']

6. “完美”的分数

虽然考试中拿到 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]])
[]
通过 GitHub 编辑 链接将在新窗口或新标签页中打开
Python Exercism

准备好开始 成绩评定 了吗?

注册 Exercism,借助 17 个概念146 个练习 和真人导师指导,学习并掌握 Python,全部免费。