所以我有一个看起来像"012 + 2 - 01 + 24"
的字符串。我希望能够快速(更少的代码)评估该表达式...
我可以在字符串上使用eval(),但我不希望012
以八进制形式(10)表示,我希望它表示为int(12)。
我的解决方案有效,但不优雅。我有点假设有一种非常好的pythonic方法来做到这一点。
我的解决方案:
#expression is some string that looks like "012 + 2 - 01 + 24"
atomlist = []
for atom in expression.split():
if "+" not in atom and "-" not in atom:
atomlist.append(int(atom))
else:
atomlist.append(atom)
#print atomlist
evalstring = ""
for atom in atomlist:
evalstring+=str(atom)
#print evalstring
num = eval(evalstring)
基本上,我撕开appart字符串,然后在其中找到数字并将它们变成int,然后我用int重建字符串(基本上删除前导0,除非0是一个数字本身)。
如何做得更好?
答案 0 :(得分:9)
我很想使用正则表达式删除前导零:
>>> re.sub(r'\b0+(?!\b)', '', '012 + 2 + 0 - 01 + 204 - 0')
'12 + 2 + 0 - 1 + 204 - 0'
这会在每个数字的开头删除零,除非数字完全由零组成:
\b
匹配单词(标记)边界; 0+
匹配一个或多个连续的零; (?!\b)
(negative lookahead)禁止匹配,其中零序列后跟一个标记边界。这种方法优于基于split()
的替代方案的一个优点是它不需要空格才能工作:
>>> re.sub(r'\b0+(?!\b)', '', '012+2+0-01+204-0')
'12+2+0-1+204-0'
答案 1 :(得分:5)
你可以使用lstrip()在一行中删除任何前导零:
>>> eval("".join(token.lstrip('0') for token in s.split()))
37
答案 2 :(得分:2)
我想这样做:
>>> s = '012 + 2 + 0 - 01 + 204 - 0'
>>> ' '.join(str(int(x)) if x.isdigit() else x for x in s.split())
'12 + 2 + 0 - 1 + 204 - 0'
如果你想处理它们,请使用float()
:)
答案 3 :(得分:1)
int
不假设前导零表示八进制数:
In [26]: int('012')
Out[26]: 12
因此,您可以使用以下代码
安全地评估表达式from operator import add, sub
from collections import deque
def mapper(item, opmap = {'+': add, '-': sub}):
try: return int(item)
except ValueError: pass
return opmap[item]
stack = deque()
# if item filters out empty strings between whitespace sequences
for item in (mapper(item) for item in "012 + 2 - 01 + 24".split(' ') if item):
if stack and callable(stack[-1]):
f = stack.pop()
stack.append(f(stack.pop(), item))
else: stack.append(item)
print stack.pop()
不是单行,但它是安全的,因为你控制了所有可以执行的功能。