python - 如何在 Python 中压缩这个 if 语句?
问题描述
我目前正在用 Python 创建一个计算器,但遇到了一个小问题:我的 if-else 语句中有 28 个条件:
if operation0 == "+" and operation1 == "+" and operation2 == "+": # First operation is addition
print(number0 + number1 + number2 + number3)
elif operation0 == "+" and operation1 == "+" and operation2 == "*":
print(number0 + number1 + number2 * number3)
elif operation0 == "+" and operation1 == "+" and operation2 == "^":
print(number0 + number1 + number2 ** number3)
elif operation0 == "+" and operation1 == "*" and operation2 == "+":
print(number0 + number1 * number2 + number3)
elif operation0 == "+" and operation1 == "*" and operation2 == "*":
print(number0 + number1 * number2 * number3)
elif operation0 == "+" and operation1 == "*" and operation2 == "^":
print(number0 + number1 * number2 ** number3)
elif operation0 == "+" and operation1 == "^" and operation2 == "+":
print(number0 + number1 ** number2 + number3)
elif operation0 == "+" and operation1 == "^" and operation2 == "*":
print(number0 + number1 ** number2 * number3)
elif operation0 == "+" and operation1 == "^" and operation2 == "^":
print(number0 + number1 ** number2 ** number3)
elif operation0 == "*" and operation1 == "+" and operation2 == "+": # First operation is multiplication
print(number0 * number1 + number2 + number3)
elif operation0 == "*" and operation1 == "+" and operation2 == "*":
print(number0 * number1 + number2 * number3)
elif operation0 == "*" and operation1 == "+" and operation2 == "^":
print(number0 * number1 + number2 ** number3)
elif operation0 == "*" and operation1 == "*" and operation2 == "+":
print(number0 * number1 * number2 + number3)
elif operation0 == "*" and operation1 == "*" and operation2 == "*":
print(number0 * number1 * number2 * number3)
elif operation0 == "*" and operation1 == "*" and operation2 == "^":
print(number0 * number1 * number2 ** number3)
elif operation0 == "*" and operation1 == "^" and operation2 == "+":
print(number0 * number1 ** number2 + number3)
elif operation0 == "*" and operation1 == "^" and operation2 == "*":
print(number0 * number1 ** number2 * number3)
elif operation0 == "*" and operation1 == "^" and operation2 == "^":
print(number0 * number1 ** number2 ** number3)
elif operation0 == "^" and operation1 == "+" and operation2 == "+": # First operation is exponentiation
print(number0 ** number1 + number2 + number3)
elif operation0 == "^" and operation1 == "+" and operation2 == "*":
print(number0 ** number1 + number2 * number3)
elif operation0 == "^" and operation1 == "+" and operation2 == "^":
print(number0 ** number1 + number2 ** number3)
elif operation0 == "^" and operation1 == "*" and operation2 == "+":
print(number0 ** number1 * number2 + number3)
elif operation0 == "^" and operation1 == "*" and operation2 == "*":
print(number0 ** number1 * number2 * number3)
elif operation0 == "^" and operation1 == "*" and operation2 == "^":
print(number0 ** number1 * number2 ** number3)
elif operation0 == "^" and operation1 == "^" and operation2 == "+":
print(number0 ** number1 ** number2 + number3)
elif operation0 == "^" and operation1 == "^" and operation2 == "*":
print(number0 ** number1 ** number2 * number3)
elif operation0 == "^" and operation1 == "^" and operation2 == "^":
print(number0 ** number1 ** number2 ** number3)
else:
print("Error")
我尝试过的没有任何效果,我在这个网站上找不到任何可以帮助我压缩代码的东西。这么多重复的 elif 是不合理的,任何数量的减少都将不胜感激。
解决方案
免责声明:该解决方案可能会使用各种概念,这些概念在此处无法解释。
要获得优先权,您必须正确解析输入。有几种方法可以做到这一点;一种常见的方法是 Dijkstra 的调车场算法。
由于这只是一个示例,我们将放弃良好实践(错误处理、类)以获得更简洁的代码。
首先,我们需要列出优先级。更高的优先级意味着运算符具有更高的优先级,因此它会更早地执行。
precedences = {
'^': 3,
'*': 2, '/': 2,
'+': 1, '-': 1
}
然后,我们需要将操作与每个操作员相关联。为此,我们可以使用operator
模块中的函数:
from operator import pow, truediv, mul, add, sub
do = {
'^': pow,
'*': mul, '/': truediv,
'+': add, '-': sub
}
最后,我们需要实现决定何时评估表达式的逻辑。首先,我们比操作多一个数字,所以我们把它放到堆栈中:
def shunt(numbers, operations):
stack = [numbers.pop(0)]
operators = []
然后,我们处理每个运算符号对。
while len(numbers):
operator = operations.pop(0)
precedence = precedences[operator]
do
当一个操作具有比当前操作更高的优先级(执行得更早)时,它会被评估(使用字典)。我们从堆栈中删除左右操作数,并从中查找适当的函数do
以评估结果:
while operators and precedences[operators[-1]] >= precedence:
[left, right], stack[-2:] = stack[-2:], []
stack.append(do[operators.pop()](left, right))
然后我们将当前运算符和数字附加到堆栈中:
operators.append(operator)
stack.append(numbers.pop(0))
在所有数字和运算符都用完后,我们评估其余的运算符,直到只剩下一个数字,然后返回:
while len(stack) > 1:
[left, right], stack[-2:] = stack[-2:], []
stack.append(do[operators.pop()](left, right))
return stack[0]
将它们放在一起(在线尝试!):
from operator import pow, truediv, mul, add, sub
precedences = {
'^': 3,
'*': 2, '/': 2,
'+': 1, '-': 1
}
do = {
'^': pow,
'*': mul, '/': truediv,
'+': add, '-': sub
}
def shunt(numbers, operations):
stack = [numbers.pop(0)]
operators = []
while len(numbers):
operator = operations.pop(0)
precedence = precedences[operator]
while operators and precedences[operators[-1]] >= precedence:
[left, right], stack[-2:] = stack[-2:], []
stack.append(do[operators.pop()](left, right))
operators.append(operator)
stack.append(numbers.pop(0))
while len(stack) > 1:
[left, right], stack[-2:] = stack[-2:], []
stack.append(do[operators.pop()](left, right))
return stack[0]
推荐阅读
- java - 从 WSDL 生成 java 类时出错
- python - 如何替换python中dict键中的单引号(')?
- r - Change Latex engine when using bookdown when knitting Markdown to PDF
- vaadin - 向用户注册会话
- c - 查找区间内回文数的算法
- python - 如何在没有交错格式的情况下在 Pandas 中附加数据帧
- r - 根据记录前后的平均值添加缺失数据
- python - 如何编辑 pandas_datetime 对象
- flutter - 如何根据用户角色创建视图以及如何创建登录 - Flutter
- python - 有没有一种按元素过滤熊猫 groupby 结果的方法?