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())