递归结构
Coddy Python 计算器项目 课程的第 9 课,共 29 课。
上一课中我们看到的结构,真正的威力体现在递归上。
来看一个包含多个运算符的计算,例如:
- 2 + 3 * 4 + 5
根据数学规则,运算有先后顺序。我们需要先计算 3 * 4,然后再计算其余部分。
下面的计算可以用以下几种方式表示为递归结构:
['+', ['+', 2, ['*', 3, 4]], 5]['+', 2, ['+', 5, ['*', 3, 4]]]['+', 5, ['+', ['*', 3, 4], 2]]
注意,最深处的简单结构始终是 ['*', 3, 4],它是最先计算的。还要注意,所有内容都基于基本结构 [op, num1, num2]。
再来看一些将计算表示为递归结构的例子:
- 2 - 3 ->
['-', 2, 3] - 1 - 2 + 3 ->
['+', ['-', 1, 2], 3] - 1 * 2 - 3 ->
['-', ['*', 1, 2], 3] - 2.3 + 3 / 4.2 - 2 ->
['-', ['+', 2.3, ['/', 3, 4.2]], 2]
挑战
中等升级 eval 函数,使其支持上文所述的递归结构。
注意:
- 当结构是简单结构,即运算符带有两个数字 时,调用
calc函数。 - 如果其中一个参数是另一个结构(列表),则递归调用
eval。
亲手试试
def calc(op, n1, n2=None):
if not isinstance(n1, int) and not isinstance(n1, float):
raise Exception('Invalid number "' + str(n1) + '"')
if n2 is None:
if op == '+' or op == 'add':
return n1
if op == '-' or op == 'sub':
return -n1
raise Exception('Invalid operator "' + op + '"')
if not isinstance(n2, int) and not isinstance(n2, float):
raise Exception('Invalid number "' + str(n2) + '"')
if op == '+' or op == 'add':
return n1 + n2
if op == '-' or op == 'sub':
return n1 - n2
if op == '*' or op == 'mul':
return n1 * n2
if op == '/' or op == 'div':
if n2 == 0:
raise Exception("Division by zero")
return n1 / n2
if op == '%' or op == 'mod':
if n2 == 0:
raise Exception("Division by zero")
return n1 % n2
if op == '^' or op == 'pow':
return n1 ** n2
raise Exception('Invalid operator "' + op + '"')
def eval(lst):
op = lst[0]
n1 = lst[1]
n2 = lst[2]
return calc(op, n1, n2)Python 计算器项目中的所有课
自己练习: Python 在线编译器