使用枚举的好处?

时间:2016-10-22 19:47:22

标签: python

我是Python的初学者。 我想知道列举一种更有效的方法吗?或者在这里没那么重要,而且只有在做更复杂的事情时才会发挥作用?

我的代码没有枚举:

for x in thing:
    if thing.index(x) % 2 == 0:
        x += 7
        print (x)
    else:
        print (x)

我的代码使用枚举:

for index,x in enumerate(thing):
    if index % 2 == 0:
        x += 7
        print (x)
    else:
        print (x)

2 个答案:

答案 0 :(得分:7)

list.index的复杂度为O(n),这意味着您将遍历列表两次以上(同时考虑for循环本身),并返回第一个索引对于给定项目,这意味着您将对具有重复项目的列表获得不正确的结果。

enumerate通过简单地生成索引和项目来解决这个问题;我不认为你可以获得比内置enumerate提供的更多的性能。

另请注意,enumerate会被懒惰地评估;大型清单的巨大优势。相反,您不想调用大型列表的index方法,即使列表中没有重复项且结果正确,您仍然会进行不必要的遍历整个清单。

答案 1 :(得分:0)

如果您对效率感到疑惑,可以使用几种工具来检查哪种解决方案/算法更有效。这称为分析

分析的第一个目标是测试代表性系统以识别什么是慢速(或使用太多RAM,或导致过多的磁盘I / O或网络I / O)。

分析通常会增加开销(典型的10x到100x减速),并且您仍然希望代码的使用方式与实际情况相似。提取测试用例并隔离您需要测试的系统部分。优选地,它已经被编写为已经在其自己的模块集中。

基本技巧包括IPython中的%timeit魔法,time.time(),timing decorator(参见下面的示例)。您可以使用这些技术来理解语句和函数的行为。

然后你有cProfile这将为你提供问题的高级视图,这样你就可以将注意力转移到关键功能上。

接下来,查看line_profiler,,它将逐行分析您选择的功能。结果将包括每行调用的次数以及每行所花费的时间百分比。这正是您需要了解的信息,以了解运行缓慢的原因以及原因。

perf stat可帮助您了解最终在CPU上执行的指令数以及CPU缓存的使用效率。这允许对矩阵运算进行高级调整。

heapy可以跟踪Python内存中的所有对象。这对于追捕奇怪的内存泄漏非常有用。如果您正在使用长时间运行的系统, 然后dowser会让您感兴趣:它允许您通过Web浏览器界面在长时间运行的过程中内省活动对象。

为了帮助您了解RAM使用率高的原因,请查看memory_profiler.这对于跟踪标记图表上的RAM使用情况特别有用,因此您可以向同事(或您自己)解释为什么某些功能会使用RAM超出预期。

示例:定义装饰器以自动执行定时测量

from functools import wraps

def timefn(fn):
    @wraps(fn)
    def measure_time(*args, **kwargs):
        t1 = time.time()
        result = fn(*args, **kwargs)
        t2 = time.time()
        print ("@timefn:" + fn.func_name + " took " + str(t2 - t1) + " seconds")
        return result
    return measure_time

@timefn
def your_func(var1, var2):
    ...

有关更多信息,我建议阅读上述内容的High performance Python(Micha Gorelick; Ian Ozsvald)。