Python:字符串为int或出错时为零,没有try / except

时间:2013-11-01 07:14:25

标签: python

本着短代码的精神......我有一个数字或空字符串的列表,我希望map(int, mylist)没有它失败。

mylist = "123//456".split("/") #['123', '', '456']
myints = <something to quickly convert the list>

编辑 我需要保留相同数量的令牌。即myints = [123, 0, 456]

我在思考map(lambda x: int(x) or 0, mylist)的某些内容,但当然这仍然会引发ValueError。有什么想法吗?


另一个编辑

一些结果(时间for xrange(1000000))......

  • 2.03s l = map(lambda x: x.isdigit() and int(x) or 0, mylist)
  • 1.37s l = [x.isdigit() and int(x) or 0 for x in mylist]
  • 1.99s l = map(lambda x: int(x) if x.isdigit() else 0, mylist)
  • 1.35s l = [int(x) if x.isdigit() else 0 for x in mylist]
  • 1.24s l = [int(x or 0) for x in mylist]
  • 1.45s l = [int(e) if e.strip() else 0 for e in mylist]
  • 4.44s the big chunk of code with try/except ergo更大更慢:)好吧,并非总是

只是将它们包括在内,因为它们没有产生所需的输出......

  • 3.71s l = map(int, re.findall('[0-9]+', "123//456"))('当前正则表达式很慢。时间和地点)
  • 1.47s l = map(int, filter(None, mylist))
  • 1.15s [int(x) for x in mylist if x](美好的时光!)

*我应该提到re.compile剃须3.71s到2.11s。

Python 2.7.3, Xeon E5-1607

myints = [int(x or 0) for x in mylist] 不仅是最快的,结果正确,而且非常短,只有29个字符。

感谢大家的投入!而不是那些贬低者:P

8 个答案:

答案 0 :(得分:4)

简短,虽然没有其他答案那么强大 - x必须是空字符串或数字:

[int(x or 0) for x in mylist]

答案 1 :(得分:2)

myints = map(lambda x: int(x) if x.isdigit() else 0, "123//456".split("/")) # returns [123, 0, 456]

如您所愿,保留相同数量的令牌,并用零替换非数字字符串

编辑:您也可以通过理解来完成:

myints = [int(x) if x.isdigit() else 0 for x in "123//456".split("/")]

答案 2 :(得分:2)

短片并不总是最好的,但这很短暂:

>>> [int(e) if e.strip() else 0 for e in "123//456".split("/")]
[123, 0, 456]

此外:

>>> map(int, (e if e.isdigit() else '0' for e in "123//456".split("/")))

答案 3 :(得分:2)

这让我觉得for循环比列表理解更具可读性。但是如果你真的想用尽可能少的代码来做,那试试这个:

myints = [int(x) if x.isdigit() else 0 for x in mylist]

显然,您可以使用任何您喜欢的值代替0来表示非数字字符串,其中包括空字符串。

for循环形式将是这样的:

myints = []
for x in mylist:
    try:
        intx = int(x)
    except (TypeError, ValueError):
        intx = 0
    finally:
        myints.append(intx)

该表单的优势在于可以处理int可以处理的任何输入,并且会想到负数 - '-7'.isidigit()将返回False,因此任何int(x) if x.isdigit() else 0 }解决方案会将'123//-7'变为[123, 0, 0]而不是[123, 0, -7]。你的问题陈述没有解决负整数,所以我不确定你需要什么。

答案 4 :(得分:1)

尝试使用list comprehension

my_ints = [int(x) for x in my_str.split('/') if x]

答案 5 :(得分:1)

使用regex

>>> import re
>>> map(int, re.findall('[0-9]+', "123//456////1231231"))
[123, 456, 1231231]

如果字符串很大,那么你可以使用re.finditer和列表理解:

>>> [int(m.group()) for m in re.finditer('[0-9]+', "123//456////1231231")]
[123, 456, 1231231]

对于edit,您可以使用str.isdigitternary expression

>>> mylist = "123//456"
>>> [int(x) if x.isdigit() else 0 for x in mylist.split('/')]
[123, 0, 456]

答案 6 :(得分:0)

为什么不在'//'拆分?

print map(int, "123//456".split('//'))

如果这不是一个选项,那么你可以这样做:

print map(int, filter(None, mylist))

或者如果你想保持相同的长度:

print map(lambda x: int(x) if x.isdigit() else 0, mylist)

答案 7 :(得分:0)

实际上这是一种有效的方法,但是对.isdigit()有额外的调用,这似乎不是必要的。

mylist = "123//456".split("/") #['123', '', '456']
myints = map(lambda x: x.isdigit() and int(x) or 0, mylist)

[123, 0, 456]