name, *line = input().split() 到底是怎么工作的
本文最后更新于4 天前,其中的信息可能已经过时,如有错误请发送邮件到184874483@qq.com

name, *line = input().split() 到底是怎么工作的

这一句其实是在做两件事:

先把用户输入的一整行,按空格切开;然后把切开后的结果“拆开”分给不同变量。

你看到的代码是:

name, *line = input().split()

可以把它先拆成两步理解:

data = input().split()
name = data[0]
line = data[1:]

也就是说,这种带 * 的写法,本质上就是一种更紧凑的“拆包”写法。


先看 input().split() 产生了什么

假设用户输入这一行:

Krishna 67 68 69

那么:

input().split()

得到的是一个列表:

['Krishna', '67', '68', '69']

注意,这里面每一项都是字符串,哪怕看起来像数字,实际上还是字符串。

所以这时候如果写:

name, *line = ['Krishna', '67', '68', '69']

它就会这样分配:

  • name 接收第一个元素:'Krishna'
  • line 接收剩下所有元素:['67', '68', '69']

所以最后结果是:

name = 'Krishna'
line = ['67', '68', '69']

星号拆包是什么意思

最直白的理解

在赋值拆包里,*变量名 的意思是:

“把剩下没分完的所有元素,都收集到这个变量里,并且装成一个列表。”

所以:

name, *line = ['Krishna', '67', '68', '69']

等价于:

name = 'Krishna'
line = ['67', '68', '69']

这里的 line 不再是单个值,而是一个列表。


为什么这里要用 *line

因为这一行输入里:

  • 第一个内容是学生名字
  • 后面的内容都是成绩

也就是说,程序想表达的是:

“第一个单独拿出来当名字,剩下的全部当成绩列表。”

这时候 *line 就特别合适。

如果不用星号,你就得手动切片:

data = input().split()
name = data[0]
line = data[1:]

两种写法都对,只是星号拆包写得更紧凑一些。


执行过程一步一步模拟

来看这段:

name, *line = input().split()
scores = list(map(float, line))
student_marks[name] = scores

假设输入是:

Malika 52 56 60

第一步:读取并切分输入

input().split()

得到:

['Malika', '52', '56', '60']

第二步:星号拆包

name, *line = ['Malika', '52', '56', '60']

结果:

name = 'Malika'
line = ['52', '56', '60']

第三步:把字符串成绩变成浮点数

scores = list(map(float, line))

等价理解为:

scores = [52.0, 56.0, 60.0]

第四步:存到字典里

student_marks[name] = scores

结果字典会变成:

{
    'Malika': [52.0, 56.0, 60.0]
}

如果前面还录入了其他学生,那么字典就会不断增加键值对。


map 到底起什么作用

一句话理解

map 的作用是:

把某个函数,依次作用到一组数据中的每一个元素上。

它的基本形式是:

map(函数, 可迭代对象)

比如:

line = ['52', '56', '60']
map(float, line)

意思就是:

  • float('52')
  • float('56')
  • float('60')

依次做一遍。

结果相当于把每个字符串都转换成浮点数。


这里为什么写 map(float, line)

因为 line 里现在还是字符串:

['52', '56', '60']

但我们后面要算平均分,必须把它们变成数字。

所以:

map(float, line)

就是把列表里的每个字符串都变成 float 类型。

再配合 list(...)

scores = list(map(float, line))

最终得到:

[52.0, 56.0, 60.0]

为什么还要再套一层 list()

这是因为在 Python 3 里,map() 返回的不是直接的列表,而是一个 map 对象。

你可以先把它理解成:

“一个还没真正展开的转换结果”

所以通常我们会写成:

list(map(float, line))

把它真正变成列表。


和熟悉的写法对比一下

已经知道这种写法:

data = input().split()
name = data[0]
scores = list(map(float, data[1:]))

这和题目中的写法:

name, *line = input().split()
scores = list(map(float, line))

本质上是一样的。

第一种写法:更直白

data = input().split()
name = data[0]
scores = list(map(float, data[1:]))

优点是初学者更容易看懂,因为每一步都展开了。

第二种写法:更紧凑

name, *line = input().split()
scores = list(map(float, line))

优点是代码更简洁,更像“第一个给名字,其余都给成绩”。

对于初学者来说,我建议你先把第二种写法自动翻译成第一种写法去理解。这样会稳很多。


最小可运行例子

你可以先单独跑这个小例子,观察变量到底变成了什么:

data = "Krishna 67 68 69".split()
print(data)

name, *line = data
print(name)
print(line)

scores = list(map(float, line))
print(scores)

运行结果大概是:

['Krishna', '67', '68', '69']
Krishna
['67', '68', '69']
[67.0, 68.0, 69.0]

从思路到代码

这道题里,人脑的思路其实是这样的:

先读入一整行数据。
这一行里,第一个是名字,后面几个是分数。
名字要单独保存,分数要收集起来。
因为输入进来的分数本来是字符串,所以还要把它们转成数字。
最后把“名字 -> 分数列表”存进字典。

把这个思路翻译成代码,就是:

name, *line = input().split()
scores = list(map(float, line))
student_marks[name] = scores

所以你可以把这句理解成:

“先切开;第一个给名字;剩下的给成绩;再把成绩从字符串改成数字;最后存进字典。”


再补几个星号拆包的例子

例 1:收集后面的所有元素

a, *b = [1, 2, 3, 4]

结果:

a = 1
b = [2, 3, 4]

例 2:前后都可以留位置

a, *b, c = [1, 2, 3, 4, 5]

结果:

a = 1
b = [2, 3, 4]
c = 5

这里的 *b 表示:

中间剩下的都给 b

例 3:只有一个剩余元素时

a, *b = [10, 20]

结果:

a = 10
b = [20]

例 4:后面没有剩余元素时

a, *b = [10]

结果:

a = 10
b = []

注意,b 仍然是列表,只不过是空列表。


常见错误与易混点

1. 以为 line 是一个字符串

不是。

name, *line = input().split()

这里的 line 是一个列表,不是单个字符串。


2. 以为 map(float, line) 会直接得到列表

在 Python 3 里不是直接列表,而是 map 对象。
通常都要这样写:

scores = list(map(float, line))

3. 忘了输入的数据本来都是字符串

input() 读进来的内容默认都是字符串。
所以:

'67'

不是数字 67,必须转换。


4. 不知道 *line 为什么能接多个值

因为带星号的变量,在拆包赋值时专门负责“收集剩余元素”。
并且收集出来的一定是列表。


你可以把这句翻译成“人话”

name, *line = input().split()

可以翻译成:

“把输入按空格拆开,第一个内容放到 name 里,剩下所有内容放到 line 这个列表里。”

而这句:

scores = list(map(float, line))

可以翻译成:

“把 line 里面每一个字符串成绩,都转成浮点数,再组成一个列表。”


本节小结

这段代码里最关键的两个点是:

星号拆包

name, *line = input().split()

表示:

  • name 接第一个元素
  • line 接剩下全部元素
  • line 是一个列表

map 的作用

list(map(float, line))

表示:

  • line 里的每个元素都执行一次 float()
  • 把字符串数字变成浮点数
  • 最后再转成列表

所以整段连起来就是:

name, *line = input().split()
scores = list(map(float, line))

意思是:

从一行输入里拿到名字和分数,并把分数字符串转换成数字列表。


练习

请你自己先不要看答案,试着写一段小程序:

题目:
用户输入一行:

Tom 80 90 100

要求你完成下面几件事:

  1. 用星号拆包拿到名字和分数部分
  2. 把分数字符串转换成整数列表
  3. 打印名字
  4. 打印分数列表

提示:

  • 先用 input().split()
  • 第一个元素给名字
  • 剩下的给列表
  • 可以试着用 map(int, ...)
文末附加内容
暂无评论

发送评论 编辑评论


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