我有一個python公式,它隨機將操作數放在數字之間。列表可以,例如,是這樣的:從字符串列表計算 - Python
['9-8+7', '7-8-6']
我想要做的就是讓每一個字符串的值,使得通過字符串循環,數組會看到9-8 + 7,並會追加8和7-8-6將附加-7。我不能將操作數的字符串轉換爲int,所以這可能嗎?或者我應該改變算法,以便不用每個隨機輸出創建一個字符串,而是立即計算它的值?
預先感謝您。
我有一個python公式,它隨機將操作數放在數字之間。列表可以,例如,是這樣的:從字符串列表計算 - Python
['9-8+7', '7-8-6']
我想要做的就是讓每一個字符串的值,使得通過字符串循環,數組會看到9-8 + 7,並會追加8和7-8-6將附加-7。我不能將操作數的字符串轉換爲int,所以這可能嗎?或者我應該改變算法,以便不用每個隨機輸出創建一個字符串,而是立即計算它的值?
預先感謝您。
您可以在列表項上做eval
,但這是一個潛在的安全漏洞,只能在您完全信任源代碼時才使用。
>>> map(eval, ['9-8+7', '7-8-6'])
[8, -7]
如果你控制的代碼生成的字符串,計算值直接聽起來像一個更好的方法(更安全,可能更快)。
這當然取決於你的表情的表現如何良好並受到限制。
由於減法與負數相加,因此可以將減法寫爲帶負數的加法。吐在+找到條款。然後將總和的條款解析爲整數,然後對它們進行求和。爲每個表達式都這樣做。
[sum(map(int,l.replace('-', '+-').split('+'))) for l in ['9-8+7','7-8-6']]
正如Fredrik指出的那樣,您可以在Python中做eval。我想我會添加一種更通用的方法,可以用任何語言工作,並且可以爲那些沒有看到它們的簡單解析器提供一些簡單的解析器。
你描述它的正式定義看起來是這樣的語言:
expr := sum
sum := prod [("+" | "-") prod]...
prod := digit [("*" | "/") digit]...
digit := '0'..'9'
這個語法(這我沒有打擾做出正確EBNF)接受這些字符串:「3」,「4 * 5/2「和」8 * 3 + 9「等等。
這給了我們一個線索如何解析它,評估沒有比我們去積累的結果更多的工作。以下是Python 2的代碼。注意代碼遵循語法的密切程度。
class ParseFail(Exception):
pass
def eval_expr(str):
value, pos = eval_sum(str, 0)
return value
def eval_sum(str, pos):
value, pos = eval_product(str, pos)
accum = value
while pos != len(str):
op = str[pos]
if not str[pos] in ['+', '-']:
raise ParseFail("Unexpected symbol at position "
"{pos} of {str}".format(str=str, pos=pos))
value, pos = eval_product(str, pos + 1)
if op == '+':
accum += value
else:
accum -= value
return accum, pos
def eval_product(str, pos):
value, pos = eval_digit(str, pos)
accum = value
while pos != len(str):
op = str[pos]
if not str[pos] in ['*', '/']:
return accum, pos
value, pos = eval_digit(str, pos + 1)
if op == '*':
accum *= value
else:
accum /= value
return accum, pos
def eval_digit(str, pos):
if not str[pos].isdigit():
raise ParseFail("Unexpected symbol at position "
"{pos} of {str}".format(str=str, pos=pos))
return int(str[pos]), pos + 1
try:
print "3 ->", eval_expr("3")
print "3*4 ->", eval_expr("3*4")
print "2+3*4-5 ->", eval_expr("2+3*4-5")
# Should raise ParseFail
print "2+3*4^2-5 ->", eval_expr("2+3*4^2-5")
except ParseFail as err:
print
print err.args[0]
下面是一個運行示例:
$ python simple_expr.py
3 -> 3
3*4 -> 12
2+3*4-5 -> 9
2+3*4^2-5 ->
Unexpected symbol at position 5 of 2+3*4^2-5
這將是很容易將它與更多的運營商,如指數運算符「^」和多位數整數延伸到一個完整的字符串計算器。括號,浮動和函數可能有點工作,但也不是那麼難。在我看來,每個程序員都應該嘗試一次。
它僅僅是'+'和'-'嗎? –