Python-хранить строку и int с помощью map (sys.стандартный ввод.с readline())
если вход содержит разделенную пробелом строку int, например-
1 3
Я могу отобразить его в массиве, используя map()
функции
arr = map(int,sys.stdin.readline().split())
или даже в двух отдельных переменных, путем
n,m = map(int,sys.stdin.readline().split())
есть ли способ использовать тот же способ для чтения строки ввода, которая содержит смешанные типы данных. например.-
foo 3
здесь foo
- строка 3
- это целое число?
5 ответов
если у вас всегда была строка и неотрицательный int:
import sys
n, m = map(lambda x: (str, int)[x.isdigit()](x) ,sys.stdin.readline().split(None, 1))
print(n,m)
но самый безопасный способ-всегда использовать try / except при литье пользовательского ввода, даже если ожидается только один тип.
по запросу Возможна проверка на отрицательный:
import sys
n, m = map(lambda x: (str, int)[x.isdigit() or x.strip("-").isdigit()](x) ,sys.stdin.readline().split())
print(n, m)
но --10
--10--
также будет пройти тест, но вызвать ошибку так снова только для вашего конкретного случая.
для этого вы должны быть в состоянии различать строки, которые могут представлять целые числа и строки, которые не могут. Пример:
def foo(s):
try:
return int(s)
except ValueError:
return s
затем вы можете нормально использовать map
:
map(foo, sys.stdin.readline().split())
приведенная выше строка для ввода:
abcdef 110
выведет:
['abcdef', 110]
можно использовать str.isdigit
чтобы проверить, можно ли привести строку к целому числу.
>>> inpt = "foo 3"
>>> [int(s) if s.isdigit() else s for s in inpt.split()]
конечно, вы можете сделать то же самое используя map
и sys.stdin.readline
С помощью lambda
>>> map(lambda s: int(s) if s.isdigit() else s, sys.stdin.readline().split())
foo 4
['foo', 4]
если вы хотите поддерживать все виды типов данных, вы можете попробовать literal_eval
и вернуться к основной нити, если это не работает.
import ast
def try_eval(string):
try:
return ast.literal_eval(string)
except ValueError:
return string
>>> map(try_eval, "42 3.14 foo 'bar' [1,2,3]".split())
[42, 3.1400000000000001, 'foo', 'bar', [1, 2, 3]]
map
- это когда вы хотите применить одно и то же преобразование к каждому элементу ввода. Это не соответствует вашему варианту использования; вы хотите рассматривать два входа по-разному. Поскольку данные имеют фиксированный формат string, а затем integer, было бы лучше проанализировать его таким образом, чтобы всегда создавать этот формат:
x, y = raw_input().split()
y = int(y)
если у вас больше столбцов, вы можете составить список функций, которые будут использоваться для обработки каждого столбца:
handlers = [str, int, int, str, float, int, int]
a, b, c, d, e, f, g = [f(x) for (f, x) in zip(handlers, raw_input().split())]
решения, предложенные другие ответы не учитывают фиксированный формат ввода. Если пользователь вводит
31 42
x
должно быть "31"
, а не 31
и если пользователь вводит
foo bar
это должно быть обнаружено как ошибка, а не назначение "bar"
to y
.
вы можете сделать быструю настройку "try / except", если вы не ищете ничего необычного.
например,
def convert(x):
try:
f = float(x)
i = int(f)
x = i if i == f else f
except:
pass
return x
arr = map(convert, sys.stdin.readline().split())