获取用户输入的数字列表

73 投票
11 回答
526386 浏览
提问于 2025-04-16 09:48

我试着用 input(Python 3)或 raw_input()(Python 2)来获取一串数字,不过用下面的代码

numbers = input()
print(len(numbers))

输入 [1,2,3]1 2 3 的结果分别是 75,看起来它把输入当成了字符串来处理。有没有什么直接的方法可以把它变成一个列表呢?也许我可以用 re.findall 来提取整数,但如果可以的话,我更想用一种更符合Python风格的方法。

11 个回答

11

使用类似Python的语法

标准库提供了一个叫做 ast.literal_eval 的功能,它可以把某些字符串当作Python代码来执行。这种方式不会带来安全风险,但它 仍然可能导致崩溃和各种异常

举个例子:在我的电脑上,执行 ast.literal_eval('['*1000 + ']'*1000) 会引发 MemoryError,尽管输入的内容只有两千字节。

文档中解释说:

提供的字符串或节点只能包含以下Python字面量结构:字符串、字节、数字、元组、列表、字典、集合、布尔值、 NoneEllipsis

(文档有一点 不太准确ast.literal_eval支持数字的加法和减法 - 但 不支持 其他运算符 - 这样它就可以支持复数。)

这对于读取和解析像Python代码格式的整数列表是足够的(例如,如果输入是 [1, 2, 3])。例如:

>>> import ast
>>> ast.literal_eval(input("Give me a list: "))
Give me a list: [1,2,3]
[1, 2, 3]

绝对不要对可能来自程序外部的输入使用 eval,无论是全部还是部分。这是一个严重的安全风险,允许输入的创建者执行任意代码。

没有足够的专业知识和严格的限制,无法 正确地对其进行沙盒处理 - 在这种情况下,使用 ast.literal_eval 显然要简单得多。这在我们与网络连接的世界中变得越来越重要。

在Python 2.x中, raw_input 相当于Python 3.x的 input;而2.x的 input() 则相当于 eval(raw_input())。因此,Python 2.x在其内置的、旨在对初学者友好的功能中暴露了一个严重的安全风险,并且持续了很多年。自2020年1月1日起,它也不再得到官方支持。它的过时程度大致相当于Windows 7。

除非绝对必要,否则不要使用Python 2.x;如果使用,请不要使用内置的 input

使用自定义语法

当然,可以根据自定义规则解析输入。例如,如果我们想读取一个整数列表,一种简单的格式是期望整数值用空格分隔。

要理解这一点,我们需要:

所有这些任务都可以通过常见的链接重复项来完成;最终的代码在这里的最佳答案中展示。

使用其他语法

与其为输入发明一种格式,我们可以期待输入采用其他现有的标准格式 - 比如JSON、CSV等。标准库中包含了解析这两种格式的工具。不过,通常不太友好的是,期望人们在提示符下手动输入这样的内容。通常这种输入会从文件中读取。

验证输入

ast.literal_eval 也会读取和解析许多 不是 整数列表的内容;因此,后续的代码如果 期望 一个整数列表,仍然需要验证输入。

除此之外,如果输入 格式不符合 预期,通常会抛出某种异常。一般来说,你会想要检查这一点,以便重复提示。请参见 询问用户输入,直到他们给出有效响应

62

处理用空格分开的数字列表要简单得多,而不是去解析Python的语法:

Python 3:

s = input()
numbers = list(map(int, s.split()))

Python 2:

s = raw_input()
numbers = map(int, s.split())
120

在Python 3.x中,使用这个。

a = [int(x) for x in input().split()]

示例

>>> a = [int(x) for x in input().split()]
3 4 5
>>> a
[3, 4, 5]
>>> 

撰写回答