Получить список чисел в качестве входных данных от пользователя
Я пытался использовать 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 ininput().split()]
Пример
>>> a = [int(x) for x ininput().split()] 345 >>> 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 также будет считывать и анализировать многие вещи, которые не являются списком целых чисел; поэтому последующему коду, который ожидает список целых чисел, все равно потребуется проверять входные данные.
Это все равно даст вам строки, но это будет список строк.
Если вам нужно сопоставить их с типом, используйте понимание списка:
numbers = [int(n, 10) for n in raw_input().split(",")] printlen(numbers)
Если вы хотите иметь возможность вводить любой тип Python и автоматически сопоставлять его и вы НЕЯВНО доверяете своим пользователям, тогда вы можете использовать eval