Python-使用map(sys.stdin.readline())存储字符串和int

Python-使用map(sys.stdin.readline())存储字符串和int,python,python-2.7,Python,Python 2.7,如果输入包含以空格分隔的int行,如- 1 3 我可以使用map()函数将其映射存储在数组中 arr = map(int,sys.stdin.readline().split()) 甚至在两个独立的变量中 n,m = map(int,sys.stdin.readline().split()) 是否有任何方法可以使用相同的方法读取包含混合数据类型的输入行。例如- foo 3 其中foo是一个字符串,3是一个整数?要做到这一点,您应该能够区分可以表示整数的字符串和不能表示整数的字符串。例如:

如果输入包含以空格分隔的int行,如-

1 3
我可以使用
map()
函数将其映射存储在数组中

arr = map(int,sys.stdin.readline().split())
甚至在两个独立的变量中

n,m = map(int,sys.stdin.readline().split())
是否有任何方法可以使用相同的方法读取包含混合数据类型的输入行。例如-

foo 3

其中
foo
是一个字符串,
3
是一个整数?

要做到这一点,您应该能够区分可以表示整数的字符串和不能表示整数的字符串。例如:

def foo(s):
    try:
        return int(s)
    except ValueError:
        return s
然后您可以正常使用
map

map(foo, sys.stdin.readline().split())
上面的输入行:

abcdef 110
将打印:

['abcdef', 110]
如果你不想找什么新奇的东西,你可以做一个快速的“尝试/例外”设置

e、 g

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())
您可以使用测试字符串是否可以转换为整数

>>> 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]
如果希望支持各种数据类型,可以尝试使用基本字符串,如果不起作用,可以使用基本字符串

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]]

如果始终有字符串和非负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--
也会通过测试,但会导致错误,因此仅针对您的特定情况。

map
适用于您希望对输入的每个元素应用相同转换的情况。这不适合您的用例;您希望以不同的方式处理这两个输入。由于数据的格式是固定的字符串,然后是整数,因此最好以始终生成该格式的方式对其进行解析:

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
foo bar
x
应该是
“31”
,而不是
31
,如果用户输入

31 42
foo bar


这应该被检测为错误,而不是将
“bar”
分配给
y

数字是否总是正整数?第一个输入是否总是被解释为字符串,第二个输入总是被解释为整数?如果是这样,则会改变输入的处理方式,并且没有一个答案能真正解决这一问题。@PadraicCunningham,不,事实上,数字显然也可以是负数。@user2357112是的,第一个输入应该是字符串,第二个输入应该是整数(正数或负数)。它是如何改变输入的处理方式的?@death-stroke:我已经发布了一个描述如何处理它的答案。太棒了。工作得很有魅力。谢谢。:-)这比试图确定数字是否为有效的
int
要干净得多。是的!这就是我要找的。啊,是的。现在应该修好了,对我来说很管用。”abc 123 4.5 6.7“退货”['abc',123,4.5,6.7]。你能解释一下我遗漏了什么吗?@AMacK:不是你最初问的,但是…通过float转换为int并不总是与直接转换为int相同,这也不是一个好主意。用
'10000000000000000'
试试,你会得到
[9999999999999999 1611392]
@Deathstroke,是的,但这确实是一个有趣的解决方案,使用Try/except是最安全的方法,它还允许使用负数。@padraickenningham,但是,如果我确信输入将是预期的形式,我是否需要检查安全性?我的意思是,我要用这个来解决在线评委的算法问题。所以我想我应该选择更快的东西,而不是更安全的东西?@death-stroke,如果是为了某个东西,你可以确定输入总是以那种形式存在,那么就确定它是好的。我只是说,总的来说,尝试是我看到的最好的方法。出于好奇,有没有办法也允许使用lambda函数的负整数呢?答案很好。由于您正在解包到
n,m
中,您可能希望通过将拆分限制为1来消除值错误的可能性。例如,
split(None,1)
isdigit
实际上并不测试字符串是否可以转换为整数,因此您不应该将其用于此目的。@abarnert我知道
isdigit
不处理负数,但是有没有一种情况下,
isdigit
会返回
True
而对
int
的转换会失败呢?我想,在至少一些2.x版本的宽幅版本中,非BMP Unicode数字会通过
isdigit
,但会被
int
拒绝。同时,除了负数之外,
isdigit
还不能处理其他事情,比如
“+3”
“2”
,以及3.0-3.2窄版本中的非BMP Unicode数字。我不知道是否只有这些情况。但这本身就是不使用它的原因:“我认为这些可能是测试的唯一问题”只是意味着“我不知道如何编写完整的测试覆盖率”。相比之下,
try
around
int
肯定会起作用。从这个问题上看,他到底是在问这个还是其他答案似乎并不清楚……因此,无论这是不是他真正想要的,都绝对值得指出。@abarnert:从评论中的澄清来看,我很确定这是正确的解释,但我可能弄错了。@user2357112和@abarnet:为了澄清,我想声明我所期望的输入格式始终是
foo 42
foo-42
。输入不包含
32 42
foo-bar
。它的格式始终为
str int