本着短代码的精神......我有一个数字或空字符串的列表,我希望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)
)......
l = map(lambda x: x.isdigit() and int(x) or 0, mylist)
l = [x.isdigit() and int(x) or 0 for x in mylist]
l = map(lambda x: int(x) if x.isdigit() else 0, mylist)
l = [int(x) if x.isdigit() else 0 for x in mylist]
l = [int(x or 0) for x in mylist]
l = [int(e) if e.strip() else 0 for e in mylist]
the big chunk of code with try/except
ergo更大更慢:)好吧,并非总是只是将它们包括在内,因为它们没有产生所需的输出......
l = map(int, re.findall('[0-9]+', "123//456"))
('当前正则表达式很慢。时间和地点)l = map(int, filter(None, mylist))
[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
答案 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.isdigit
和ternary 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]