If the input contains a space separated line of int, like-
1 3
I can map store it in an array using the map()
function
arr = map(int,sys.stdin.readline().split())
or even in two separate variables, by
n,m = map(int,sys.stdin.readline().split())
Is there any way to use the same way to read an input line that contains mixed data types. eg.-
foo 3
where foo
is a string and 3
is an integer?
If you always had a string and non negative int:
import sys
n, m = map(lambda x: (str, int)[x.isdigit()](x) ,sys.stdin.readline().split(None, 1))
print(n,m)
But the safest way is always to use a try/except when casting user input even when only expecting one type.
As requested checking for negative is possible:
import sys
n, m = map(lambda x: (str, int)[x.isdigit() or x.strip("-").isdigit()](x) ,sys.stdin.readline().split())
print(n, m)
But --10
--10--
would also be pass the test but cause an error so again only for your specific case.
To do that you should be able to discriminate between strings that can represent integers and strings that cannot. An example is:
def foo(s):
try:
return int(s)
except ValueError:
return s
Then you can normally use map
:
map(foo, sys.stdin.readline().split())
The above line for input:
abcdef 110
will print:
['abcdef', 110]
You could use str.isdigit
to test whether the string can be cast to an integer number.
>>> inpt = "foo 3"
>>> [int(s) if s.isdigit() else s for s in inpt.split()]
Of course, you can do the same using map
and sys.stdin.readline
using a lambda
>>> map(lambda s: int(s) if s.isdigit() else s, sys.stdin.readline().split())
foo 4
['foo', 4]
If you want to support all sorts of data types, you can try to literal_eval
and fall back to the basic string if that does not work.
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
is for when you want to apply the same transformation to every element of the input. That doesn't fit your use case; you want to treat the two inputs in different ways. Since the data has a fixed format of string, then integer, it'd be best to parse it in a way that always produces that format:
x, y = raw_input().split()
y = int(y)
If you have more columns, you could make a list of which function to use to handle each column:
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())]
The solutions suggested by the other answers don't account for the fixed format of the input. If the user inputs
31 42
x
should be "31"
, not 31
, and if the user inputs
foo bar
that should be detected as an error, rather than assigning "bar"
to y
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With