如何改进此 Python 代码以提高效率?

Posted

技术标签:

【中文标题】如何改进此 Python 代码以提高效率?【英文标题】:How can I improve this Python code to be more efficient? 【发布时间】:2017-06-25 01:27:08 【问题描述】:

我刚刚开始学习 Python(我第一次涉足编码),这是我第一次发帖......我希望我不会通过问这个问题来滥用论坛(我基本上是在请专家帮我学习)。如果社区对此不赞成,请告诉我。

对于密歇根公开课程的这项作业,我被指示要求用户输入,直到用户输入“完成”,此时代码应计算最大、最小、总和和平均值。在我所有的测试运行中,它运行良好。但我觉得可能有一种更简单的方法来编写这段代码。谁能提供改进建议?

largest = None
smallest = None
count = 0
sum = 0
while True:
    try:
        num = raw_input("Enter a number: ")
        if num == "done" : break
        num = float(num)
        count = count + 1
        sum = sum + num
        avg = sum/count
        if largest is None:
            largest = num
        if smallest is None:
            smallest = num
        if num < smallest:
            smallest = num
        elif num > largest:
            largest = num
        continue
    except: print 'Invalid input'

print "Maximum is", int(largest)
print "Minimum is", int(smallest)
print "Count:", int(count)
print "Sum:", int(sum)
print "Average:", avg

【问题讨论】:

你为什么使用float,后来又转换回int 我想平均为浮点数,但其他一切都是整数。如果我没有指定 int 或 float,那么非数字值将在“try”子句中起作用。但是如果我从 int 开始,那么我就无法获得浮点数(平均)。这有意义吗?有没有更好的方法? 【参考方案1】:

这里有几件事:

您可以删除continue 语句,因为它是循环的结尾; 您可以将if 语句压缩成if largest is None or num &gt; largest: 这将短路并使循环变小; 你可以用x += y代替x = x + y;和 您不必计算循环的平均值;循环结束时计算一次就足够了。

所以:

largest = None
smallest = None
count = 0
sum = 0
while True:
    try:
        num = raw_input("Enter a number: ")
        if num == "done" : break
        num = float(num)
        count += 1
        sum += num
        if largest is None or num > largest:
            largest = num
        if smallest is None or num < smallest:
            smallest = num
    except: print 'Invalid input'

print "Maximum is", int(largest)
print "Minimum is", int(smallest)
print "Count:", int(count)
print "Sum:", int(sum)
print "Average:", sum/count

但就big oh而言,你并不能提高多少:计算总和等只需要O(n),而且还需要花费O( n) 无论如何都要读取输入。

还有一些软件工程建议:不要使用笼统的异常,始终指定您期望的异常:

largest = None
smallest = None
count = 0
sum = 0
while True:
    try:
        num = raw_input("Enter a number: ")
        if num == "done" : break
        num = float(num)
        count += 1
        sum += num
        if largest is None or num > largest:
            largest = num
        if smallest is None or num < smallest:
            smallest = num
    except ValueError: print 'Invalid input'

print "Maximum is", int(largest)
print "Minimum is", int(smallest)
print "Count:", int(count)
print "Sum:", int(sum)
print "Average:", sum/count

【讨论】:

非常感谢!这一切都非常有帮助!是否建议主要指定异常以使代码更清晰(用于调试等)?还是有其他好处? @LaurenGains***:在这种情况下,这并不重要。但是比如说你还要在循环中打开文件,等等。现在说打开文件崩溃:你想显示 Invalid input? 可能不是,你想显示一条专用消息,或者让程序终止。如果你定义函数,你应该只处理你认为你可以在那个级别处理的异常,提醒应该被传递到上面的级别(在调用堆栈中)并且应该在那个级别处理地点。 好的好的,所以根据我在循环中所做的事情,错误(函数除外)会有所不同。我想确定我期望的错误,并做出适当的回应。那么,我也可以有两个例外?尝试.....除了值错误:...除了一些其他错误:... @LaurenGains***:是的,或者只是一个,除了让函数的调用者解决另一个错误。此外,在大多数(复杂)代码中,您并不完全知道您可能会遇到什么错误:您调用了一个函数,但该函数的作用是未知的。【参考方案2】:

实现此目的的另一种方法是将所有输入存储在一个列表中,然后使用内置函数min()max()len()sum() 来查找值:

num=raw_input("Enter a number: ")
nums=[]
while num!="done":       #check if user has finished entering inputs
    try:
        nums.append(int(num))       #append the input as an integer to a list
        num=raw_input("Enter a number: ")   #get another input
    except ValueError:
        print "Invalid input"

print "Maximum is",max(nums)
print "Minimum is",min(nums)
print "Count:",len(nums)
print "Sum: ",sum(nums)
print "Average: ",sum(nums)/len(nums)

输出:

Enter a number: 1
Enter a number: 2
Enter a number: 3
Enter a number: 4
Enter a number: 5
Enter a number: 6
Enter a number: done
Maximum is 6
Minimum is 1
Count: 6
Sum:  21
Average:  3.5

【讨论】:

我认为唯一的问题是,如果您输入数十亿个数字,您将耗尽内存。 谢谢 - 我会再看看列表。 @WillemVanOnsem 如果使用列表,内存是否只是一个问题?因此,如果我期待数十亿个数字,我不会使用列表吗?

以上是关于如何改进此 Python 代码以提高效率?的主要内容,如果未能解决你的问题,请参考以下文章

这9个提高效率的Python工具,太赞了

提高python执行效率的方法?

如何修改在 codeigniter 中完成的图像处理功能以提高效率

北大青鸟设计培训:怎样才能提高Python运行效率?

八个提高效率的VSCode必备扩展插件

八个提高效率的VSCode必备扩展插件