【问题标题】:Simplifying code - perform mathematical operations based on operator简化代码 - 基于运算符执行数学运算
【发布时间】:2017-03-08 09:25:27
【问题描述】:

以下是 Python 中计算器的代码:

import time
#Returns the sum of num1 and num2
def add(num1, num2):
    return num1 + num2

#Returns the difference of num1 and num2
def subtract(num1, num2):
    return num1 - num2

#Returns the quotient of num1 and num2
def divide(num1, num2):
    return num1 / num2

#Returns the product of num1 and num2
def multiply(num1, num2):
    return num1 * num2

#Returns the exponentiation of num1 and num2
def power(num1, num2):
    return num1 ** num2

import time

def main ():
    operation = input("What do you want to do? (+, -, *, /, ^): ")
    if(operation != "+" and operation != "-" and operation != "*" and operation != "/" and operation != "^"):
        #invalid operation
        print("You must enter a valid operation")
        time.sleep(3)
    else:
        var1 = int(input("Enter num1: ")) #variable one is identified
        var2 = int(input("Enter num2: ")) #variable two is identified
        if(operation == "+"):
            print (add(var1, var2))
        elif(operation == "-"): 
            print (subtract(var1, var2))
        elif(operation == "/"): 
            print (divide(var1, var2))
        elif(operation == "*"):
            print (multiply(var1, var2))
        else:
            print (power(var1, var2))
main()
input("Press enter to exit")
exit()

大约 30 分钟前,我找到了我的旧 Python 文件夹,并查看了我 8 个月前的所有基本脚本。我找到了我的计算器迷你脚本,并认为用尽可能少的行重新创建它会很有趣(我刚刚学习 lambda)。这是我所拥有的:

main = lambda operation,var1,var2: var1+var2 if operation=='+' else var1-var2 if operation=='-' else var1*var2 if operation=='*' else var1/var2 if operation=='/' else 'None'
print(main(input('What operation would you like to perform? [+,-,*,/]: '),int(input('Enter num1: ')),int(input('Enter num2: '))))
input('Press enter to exit')

我知道这是一个基于我的具体情况的个人问题,但如果能帮助我缩短它,我将不胜感激。有没有办法让它更 Pythonic?我是否正确使用了 lambda?有没有办法处理我的缩短版本中的错误?任何帮助,将不胜感激。我对此很陌生。谢谢!

【问题讨论】:

  • 为了让它更pythonic,把方法放回去,让它可读
  • 另外,可能更适合Code Review,但发帖前请查看他们的指南
  • @Adler:添加了答案。这是你需要的吗?如果您实现了您想要的其他人在将来查看它作为参考,请将答案标记为已接受

标签: python python-3.x lambda error-handling operators


【解决方案1】:

为了简化代码,我建议:

  1. 在字典的帮助下创建一个函数来执行操作

    注意:我根据用户提到的要求使用lambda 函数来替代。我个人会使用operator

    使用operator

    import operator
    
    def perform_operation(my_operator):
        return {
            '+': operator.add,
            '-': operator.sub,
            '*': operator.mul,
            '/': operator.truediv,  # "operator.div" in python 2
            '^': operator.pow,
       }.get(my_operator, '^')  # using `^` as defualt value since in your 
                                # "else" block you are calculating the `pow` 
    

    使用lambda

    def perform_operation(my_operator):
        return {
            '+': lambda x, y: x + y,
            '-': lambda x, y: x - y,
            '*': lambda x, y: x * y,
            '/': lambda x, y: x / float(y), 
            '^': lambda x, y: x ** y,
       }.get(my_operator, '^')  # using `^` as defualt value since in your 
                                # "else" block you are calculating the `pow()`
    

    示例运行:

    >>> perform_operation('/')(3, 5)
    0.6
    

    PS:看一下定义你就会明白为什么使用operatorlambda 更pythonic

  2. 更新您的 else 块以调用它

    var1 = int(input("Enter num1: ")) 
    var2 = int(input("Enter num2: ")) 
    perform_operation(operation)(var1, var2)  # Making call to function created above
    # THE END - nothing more in else block
    
  3. 简化您的if 条件

    if operation not in ["+", "-", "*", "/", "^"]:
        # invalid operation
    

【讨论】:

  • 哇,谢谢!我不知道operator,它让一切变得更容易解释。将来我一定会使用它。 Lambda 令人困惑,而且常常难以阅读。感谢您的回答。
【解决方案2】:

我知道这是一个有趣的自我挑战(你对它的压缩程度给我留下了深刻的印象),但我不妨像你问的那样就 lambda 和 pythonicity 提供一些一般性建议。仅在执行内联代码时使用它们。

PEP-8 建议使用 lambda 的唯一好处是它们可以嵌入到更大的表达式中。例如:

result = sorted(some_weird_iterable, key=lambda x: abs(x[0] - x[-1]))

当您想为方法分配标识符时,请始终使用def,因为它为您提供了堆栈跟踪和理解方面的宝贵信息。事实上,如果它超出了最微不足道的情况,我建议完全避免使用 lambda,以便更清楚地了解您在做什么。

def as_the_bird_flies_distance(x):
    return abs(x[0] - x[-1])

result = sorted(some_weird_iterable, key=as_the_bird_flies_distance)

使某些东西更“Pythonic”的概念不是缩短它。但为了使其更易于阅读、维护和扩展。

Python 2.7.11 (default, Jan 22 2016, 08:29:18) 
[GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import this
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!

【讨论】:

  • 感谢您的提示。当我第一次发现lambda时,我在一个表达式中的一个pygame文件中找到了它。我很困惑为什么有人会费心让事情变得比他们需要的更复杂,但现在我明白了。 Lambda 很有用,因为它避免了跳来跳去(并且可以嵌入在一行中,就像您说的那样),但是当您创建的函数不简单时,它会令人困惑。那是lambda的想法吗?感谢您的回复。我终于明白为什么首选更长、更间隔的代码了。
  • @AdlerWeber 绝对。如果 lambda 不能帮助清晰,请不要使用它。这会使您的代码更难调试,并且在您稍后回来尝试修改它时让您感到困惑。
猜你喜欢
  • 2019-07-21
  • 1970-01-01
  • 1970-01-01
  • 2011-03-02
  • 2012-01-20
  • 2011-06-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多