我希望有一个函数,该函数接受一个函数字符串,例如'x**2+x'
或'log(x)'
,并将一个数字作为x,并返回一个数字。
例如:
translate(2, "x**2") return 4
translate(10, "x**2") return 100
这是我尝试过的。但是,我只能处理x的一位数字。
def translate(x, function):
func = function.replace('x', str(x))
res = 0
i = 0
while i in range(len(function)):
if func[i] == '*':
if func[i+1] == '*':
res = res**int(func[i+2])
i+=3
else:
res *= int(func[i+1])
i+=2
elif func[i] == '+':
res += int(func[i+1])
i+=2
elif func[i] == '-':
res -= int(func[i+1])
i+=2
elif func[i] == 'l':
res += math.log(int(func[i+3]))
i+=4
else:
res += int(func[i])
i+=1
return res
编辑:我只需要一个简单的翻译函数,因为我没有传递疯狂的复杂函数。
答案 0 :(得分:1)
编辑: 似乎有很多关于eval()使用不安全的争论,应该在有人使用它之前提及 看到这个线程: Why is using 'eval' a bad practice?
使用内置方法eval()
。
def translate(x, function):
return eval(function)
result = translate(10, "x**2")
print(result)
输出:100
Edit2 :另一种无需评估的方法
def translate(s):
symbols = ['+', '-', '*', '/']
buff = ''
num = []
operations = []
for i, c in enumerate(s):
if c in symbols: # check for operators
# check for double operators like **
if s[i + 1] in symbols: # i.e. checking the first '*' in '**'
operations.append(2 * c)
continue
elif s[i - 1] in symbols: # i.e. checking the second '*' in '**'
num.append(float(buff))
buff = ''
continue
operations.append(c)
num.append(float(buff))
buff = ''
continue
else:
buff += c
num.append(float(buff))
print('input string:', s)
print('numbers:', num)
print('operations', operations)
# "power calculations" to be done first
for i, x in enumerate(operations):
if x == '**':
num[i] = perform[operations[i]](num[i], num[i + 1])
num.pop(i + 1)
operations.pop(i)
# multiply/division
for i, x in enumerate(operations):
if x in ['*', '/']:
num[i] = perform[operations[i]](num[i], num[i + 1])
num.pop(i + 1)
operations.pop(i)
# last addition/subtraction
for i, op in enumerate(operations):
if op == '-':
num[i + 1] = -num[i + 1]
return sum(num)
# define all operations you need, no need to add + or -
perform = {'*': lambda x, y: x * y, '/': lambda x, y: x / y, '**': lambda x, y: x ** y }
result = translate('5+3+10**2+210-30/2')
print('result =', result)
输出:
input string: 5+3+10**2+210-30/2
numbers: [5.0, 3.0, 10.0, 2.0, 210.0, 30.0, 2.0]
operations ['+', '+', '**', '+', '-', '/']
result = 303.0
Edit3: 较短的正则表达式
import re
def translate(s):
num = re.findall(r'\d+', s) # '\d' means digits only
operations = re.findall(r'\D+', s) # '\D' means anything but digits
print('input string:', s)
print('numbers:', num)
print('operations', operations)
# "power calculations" to be done first
for i, x in enumerate(operations):
if x == '**':
num[i] = perform[operations[i]](num[i], num[i + 1])
num.pop(i + 1)
operations.pop(i)
# multiply/division
for i, x in enumerate(operations):
if x in ['*', '/']:
num[i] = perform[operations[i]](num[i], num[i + 1])
num.pop(i + 1)
operations.pop(i)
# last addition/subtraction
for i, op in enumerate(operations):
if op == '-':
num[i + 1] = -num[i + 1]
return sum(num)
# define all operations you need, no need to add + or -
perform = {'*': lambda x, y: x * y, '/': lambda x, y: x / y, '**': lambda x, y: x ** y }
result = translate('5+3+10**2+210-30/2')
print('result =', result)