Вопрос-Ответ

Get a list of numbers as input from the user

Получить список чисел в качестве входных данных от пользователя

Я пытался использовать input (Py3) /raw_input() (Py2) для получения списка чисел, однако с кодом

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

входные данные [1,2,3] и 1 2 3 дают результат 7 и 5 соответственно – похоже, что входные данные интерпретируются так, как если бы это была строка. Есть ли какой-либо прямой способ составить из этого список? Возможно, я мог бы использовать re.findall для извлечения целых чисел, но, если возможно, я бы предпочел использовать более питоновское решение.

Переведено автоматически
Ответ 1

В 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]
>>>
Ответ 2

Гораздо проще разобрать список чисел, разделенных пробелами, чем пытаться разобрать синтаксис Python:

Python 3:

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

Python 2:

s = raw_input()
numbers = map(int, s.split())
Ответ 3

Использование синтаксиса, подобного Python

Стандартная библиотека предоставляет ast.literal_eval, которая может оценивать определенные строки так, как если бы они были кодом Python. Это не создает угрозы безопасности, но все равно может приводить к сбоям и множеству исключений.

Например: на моей машине ast.literal_eval('['*1000 + ']'*1000) будет поднят MemoryError, даже если входные данные составляют всего два килобайта текста.

Как описано в документации:


Предоставленная строка или узел могут состоять только из следующих литеральных структур Python: строк, байтов, чисел, кортежей, списков, dicts, наборов, логических значений, None и Ellipsis.


(Документация немного неточна. 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 подвергал критической угрозе безопасность свою встроенную функциональность, разработанную специально для начинающих, и делал это в течение многих лет. Он также официально не поддерживается с 1 января 2020 года. Он примерно так же устарел, как Windows 7.

Не используйте Python 2.x без крайней необходимости; если вы это сделаете, не используйте встроенный input.

Использование вашего собственного синтаксиса

Конечно, очевидно, что можно проанализировать входные данные в соответствии с пользовательскими правилами. Например, если мы хотим прочитать список целых чисел, один простой формат - ожидать целочисленные значения, разделенные пробелом.

Чтобы интерпретировать это, нам нужно:

Все эти задачи выполняются обычными связанными дубликатами; результирующий код показан в верхнем ответе здесь.

Использование других синтаксисов

Вместо того, чтобы изобретать формат для входных данных, мы могли бы ожидать ввода в каком-либо другом существующем стандартном формате, таком как JSON, CSV и т.д. Стандартная библиотека включает инструменты для анализа этих двух. Однако, как правило, не очень удобно ожидать, что люди будут вводить такие входные данные вручную в командной строке. Обычно такого рода входные данные будут считываться из файла.

Проверка входных данных

ast.literal_eval также будет считывать и анализировать многие вещи, которые не являются списком целых чисел; поэтому последующему коду, который ожидает список целых чисел, все равно потребуется проверять входные данные.

Кроме того, если входные данные не отформатированы должным образом, как правило, будет выдано какое-либо исключение. Как правило, вы захотите проверить это, чтобы повторить запрос. Пожалуйста, смотрите, как запрашивать у пользователя входные данные, пока он не даст правильный ответ.

Ответ 4

Вы можете использовать .split()

numbers = raw_input().split(",")
print len(numbers)

Это все равно даст вам строки, но это будет список строк.

Если вам нужно сопоставить их с типом, используйте понимание списка:

numbers = [int(n, 10) for n in raw_input().split(",")]
print len(numbers)

Если вы хотите иметь возможность вводить любой тип Python и автоматически сопоставлять его и вы НЕЯВНО доверяете своим пользователям, тогда вы можете использовать eval

2023-04-27 00:46 python list