for _ in range(int(input())):
本文最后更新于4 天前,其中的信息可能已经过时,如有错误请发送邮件到184874483@qq.com

这一句 for _ in range(int(input())):,它这个是什么意思呢?我们很少看到有这个_占位符

先回答最for _ in range(int(input())):

这一句可以拆成 3 小部分来看:

for _ in range(int(input())):

它的意思其实是:

“先输入一个整数,表示要重复多少次,然后把下面缩进的代码执行这么多次。”

比如输入是:

5

那么这一句就相当于:

“下面的代码循环执行 5 次。”


int(input()) 是什么意思

先看里面这一部分:

input()

作用是:从键盘读入一行内容。

但是 input() 读出来的内容默认是字符串类型,也就是 str

比如你输入:

5

实际上 input() 得到的是:

'5'

它是字符串,不是整数。

所以要再用 int() 转一下:

int(input())

这样 '5' 就变成了整数 5


range(int(input())) 是什么意思

假设输入了 5,那么:

range(5)

会生成一个“循环 5 次”的范围,对应的值依次是:

0, 1, 2, 3, 4

所以这句:

for _ in range(5):

就表示循环 5 次。


这个 _ 到底是什么

初学者确实比较少见到这个写法。

_ 本质上也是一个变量名,它不是特殊语法,不是什么占位符关键字。

也就是说,这样写是合法的:

for i in range(5):
    print(i)

也同样可以这样写:

for _ in range(5):
    print('hello')

区别在于:

  • i 表示“我等会儿可能会用这个循环变量”
  • _ 表示“这个循环变量我不用,我只是想重复执行几次”

比如这题里,我们只想循环输入学生信息 N 次,但并不关心这是第几次,所以常写成:

for _ in range(int(input())):

意思就是:

“循环若干次,但每次的编号我不需要。”


所以 _ 不是“占位符语法”,而是一种习惯写法

更准确地说:

  • _ 只是一个普通变量名
  • 但程序员约定俗成地把它写成“我不用这个变量”

例如下面两段代码效果一样:

for i in range(3):
    name = input()
for _ in range(3):
    name = input()

只是第二种更能表达你的意思:
“我只关心循环 3 次,不关心 i 是多少。”


这道题的数据到底是怎么存的

核心点:students = [] 明明是个列表,为什么后面又能 student[0]student[1] 呢?

关键就在于:students 不是普通的一层列表,而是一个嵌套列表。

也就是:列表里面放的还是列表。


先看最开始这句

students = []

这表示先创建一个空列表。

一开始里面什么都没有:

students = []

每次读入一个学生后,放进去一份 [name, score]

代码是:

name = input()
score = float(input())
students.append([name, score])

假设输入的是:

Harry
37.21

那么这一轮会得到:

name = 'Harry'
score = 37.21

然后执行:

students.append([name, score])

相当于把这个小列表:

['Harry', 37.21]

加入到 students 里面。

此时:

students = [['Harry', 37.21]]

如果继续输入第二个学生呢

再输入:

Berry
37.21

又会加入一个小列表:

['Berry', 37.21]

这时 students 变成:

students = [['Harry', 37.21], ['Berry', 37.21]]

如果再输入:

Tina
37.2

那么就会变成:

students = [['Harry', 37.21], ['Berry', 37.21], ['Tina', 37.2]]

所以 students 的结构到底是什么

你可以把它理解成:

“一个班级名单表,表里的每一行都是一个学生的信息。”

结构像这样:

students 里面的元素含义
['Harry', 37.21]一个学生的姓名和分数
['Berry', 37.21]一个学生的姓名和分数
['Tina', 37.2]一个学生的姓名和分数

所以:

  • students 是“大列表”
  • 里面每个元素 student 是“小列表”
  • 小列表里有两个内容:姓名、分数

为什么后面可以写 student[0]student[1]

看这段:

for student in students:
    scores.append(student[1])

这里的 for student in students 意思是:

“把 students 里的每一个元素依次取出来,临时放到变量 student 中。”

注意:

这里的 student 不是整个 students,它只是 students 里的其中一个元素。

students 里的每一个元素本身又是一个列表,比如:

['Harry', 37.21]

那么:

  • student[0] 就是第一个元素,也就是姓名
  • student[1] 就是第二个元素,也就是分数

例如当:

student = ['Harry', 37.21]

那么:

student[0]   # 'Harry'
student[1]   # 37.21

你可以这样理解“外层列表”和“内层列表”

外层列表

students

表示“全班所有学生”。

内层列表

student

表示“某一个学生的这一行数据”。

所以:

students[0]

表示第 1 个学生的整行数据,比如:

['Harry', 37.21]

而:

students[0][0]

表示第 1 个学生的名字:

'Harry'

students[0][1] 表示第 1 个学生的分数:

37.21

用一个最小例子把“存”和“取”完整演示一遍

先存

students = []

students.append(['Harry', 37.21])
students.append(['Berry', 37.21])
students.append(['Tina', 37.2])

print(students)

输出:

[['Harry', 37.21], ['Berry', 37.21], ['Tina', 37.2]]

这说明 students 里装着多个“小列表”。


再取

students = [['Harry', 37.21], ['Berry', 37.21], ['Tina', 37.2]]

print(students[0])      # 第一个学生整行数据
print(students[0][0])   # 第一个学生名字
print(students[0][1])   # 第一个学生分数

输出:

['Harry', 37.21]
Harry
37.21

回到你这道题,整段代码是怎么一步步运行的

原代码:

if __name__ == '__main__':
    students = []
    for _ in range(int(input())):
        name = input()
        score = float(input())
        students.append([name, score])
        
    scores = []
    for student in students:
        scores.append(student[1])    
 
    second_lowest = sorted(set(scores))[1]

    names = []
    for student in students:
        if student[1] == second_lowest:
            names.append(student[0])
            
    names.sort()        

    for name in names:
        print(name)

下面我按执行顺序给你拆开。


第一步:读入学生人数

for _ in range(int(input())):

假设输入:

5

那么表示下面要循环 5 次,也就是要读入 5 个学生的信息。


第二步:把每个学生的信息存到 students

每次循环执行:

name = input()
score = float(input())
students.append([name, score])

假设依次输入:

Harry
37.21
Berry
37.21
Tina
37.2
Akriti
41
Harsh
39

循环结束后,students 变成:

[
    ['Harry', 37.21],
    ['Berry', 37.21],
    ['Tina', 37.2],
    ['Akriti', 41.0],
    ['Harsh', 39.0]
]

第三步:把所有分数单独取出来

scores = []
for student in students:
    scores.append(student[1])

这里每次取出一个学生的小列表。

例如:

  • 第一次 student = ['Harry', 37.21]
  • 第二次 student = ['Berry', 37.21]
  • 第三次 student = ['Tina', 37.2]

然后 student[1] 就是每个学生的分数。

最后 scores 变成:

[37.21, 37.21, 37.2, 41.0, 39.0]

第四步:找出第二低分

second_lowest = sorted(set(scores))[1]

这句可以拆开理解。

set(scores)

去重。

set([37.21, 37.21, 37.2, 41.0, 39.0])

结果相当于:

{37.2, 37.21, 39.0, 41.0}

sorted(...)

排序后变成列表:

[37.2, 37.21, 39.0, 41.0]

[1]

取排序后的第 2 个元素。

因为下标从 0 开始:

  • [0] 是最低分
  • [1] 是第二低分

所以:

second_lowest = 37.21

第五步:找出所有第二低分对应的名字

names = []
for student in students:
    if student[1] == second_lowest:
        names.append(student[0])

意思是:

遍历每个学生,如果这个学生的分数等于第二低分,就把他的名字加进 names

最后得到:

['Harry', 'Berry']

第六步:按字母排序名字

names.sort()

排序后:

['Berry', 'Harry']

第七步:一个名字一行输出

for name in names:
    print(name)

输出:

Berry
Harry

从思路到代码:这题应该怎么想

这题不要一上来就硬写代码,先想清楚步骤。

第一步先想:我要存什么

每个学生有两项信息:

  • 姓名
  • 分数

所以一个学生可以存成:

[name, score]

多个学生就可以存成:

students = [
    [name1, score1],
    [name2, score2],
    ...
]

第二步再想:我要找什么

题目要找的是:

“第二低分对应的学生姓名”

所以应该先拿到所有分数,找出第二低分,再回头找哪些学生分数等于它。


第三步翻译成代码

先读入并存储:

students = []
for _ in range(int(input())):
    name = input()
    score = float(input())
    students.append([name, score])

再提取所有分数:

scores = []
for student in students:
    scores.append(student[1])

再找第二低分:

second_lowest = sorted(set(scores))[1]

再找名字:

names = []
for student in students:
    if student[1] == second_lowest:
        names.append(student[0])

最后排序输出:

names.sort()
for name in names:
    print(name)

常见错误与易混点

1. 把 studentsstudent 搞混

这是初学者最容易混的地方。

  • students:整个学生列表
  • student:其中一个学生的小列表

比如:

for student in students:

这里的 student 不是“所有学生”,只是“当前这一个学生”。


2. 以为 student[0] 是从输入里直接读出来的

不是的。

student[0] 的前提是:student 本身是一个列表,比如:

['Harry', 37.21]

所以才有:

student[0]   # 姓名
student[1]   # 分数

3. 不理解为什么 [1] 是第二低分

因为排序后下标从 0 开始。

例如:

[37.2, 37.21, 39.0, 41.0]
  • 0 号位置:最低分
  • 1 号位置:第二低分

4. 把 sort()sorted() 用混

这里你前面已经碰到过这个问题了,顺便再强调一下:

names.sort()

是“原地排序”,直接改原列表。

而:

sorted(scores)

是“返回一个新列表”。

这题里两种都能用,但你要知道区别。


一个更直观的“数据结构图”

假设输入完之后:

students = [
    ['Harry', 37.21],
    ['Berry', 37.21],
    ['Tina', 37.2]
]

那么可以把它想成这样:

外层位置内层列表内容含义
students[0]['Harry', 37.21]第一个学生
students[1]['Berry', 37.21]第二个学生
students[2]['Tina', 37.2]第三个学生

继续往里取:

表达式结果含义
students[0][0]'Harry'第一个学生的名字
students[0][1]37.21第一个学生的分数
students[1][0]'Berry'第二个学生的名字
students[1][1]37.21第二个学生的分数

最小可运行例子

可以先单独运行这个小例子,专门练“列表里套列表”的存取:

students = []

students.append(['Tom', 80])
students.append(['Alice', 90])

print(students)        # 整个列表
print(students[0])     # 第一个学生整行数据
print(students[0][0])  # 第一个学生名字
print(students[0][1])  # 第一个学生分数

运行结果:

[['Tom', 80], ['Alice', 90]]
['Tom', 80]
Tom
80

这个例子看懂了,你对这题的“数据怎么存、怎么取”就会清楚很多。


本节小结

这道题你现在最需要抓住 3 个点。

第一,for _ in range(int(input())): 的意思是:
先输入一个整数 N,然后把下面代码执行 N 次。这里的 _ 只是一个“我不需要这个循环变量”的习惯写法。

第二,students = [] 虽然是列表,但它存进去的每个元素又是一个小列表,所以它是一个“嵌套列表”。

第三,student[0]student[1] 不是在取 students,而是在取“某一个学生的小列表”里的第 1 项和第 2 项:

  • student[0] 是姓名
  • student[1] 是分数

你可以把它理解成:
students 是“全班名单表”,student 是“其中一行”。


练习

请你自己写一个小程序,不用找第二低分,只做下面这件事:

读入 3 个学生的姓名和分数,存进 students,最后打印:

  1. 整个 students
  2. 第 1 个学生的名字
  3. 第 2 个学生的分数

提示

先把每个学生存成:

[name, score]

再把它 append()students 里。
打印第 1 个学生名字时,想一想应该是先取“第几个学生”,还是先取“姓名/分数”。

文末附加内容
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇