python调优(一)

Python调优

一直给大家分享机器学习呀、算法呀、数学呀等等的,其实工程的东西说的比较少,本文介绍Python的性能优化,再好的算法也需要优雅的调优将来才能走的更远,对于算法来说Python几乎是天天不离手,所以对于Python的理解必须要强过其他人,否则你怎么保证你的程序是最好呢?

要改善应用程序的性能,最有效的方式之一是使用更合适的算法和数据结构。 Python标准库提供了大量现成的算法和数据结构,你可在应用程序中直接使用它们 。 本文将会从这个方面来介绍合理使用python自带的函数库。

列表

在访问、修改和附加元素方面,列表表现得非常出色。 要访问或修改元素,需要从底层数组 的相应位置获取对象引用,因此其复杂度为 0(1)。 附加元素的速度也非常快。 当你创建一个空列 表时,将分配一个长度固定的数组 ;而当你插入元素时,数组中的位置将逐渐被填满。 当所有位 置都被占据后,列表需要增大其底层数组的长度,进而触发内存重新分配,这需要的时间为 0(的。 尽管如此,内存分配操作并不频繁,因此附加操作的时间复杂度接近于 0(1)。

在列表开头(或中间)添加或删除元素的操作可能在效率方面存在问题。 在列表开头插入或 删除元素时,后续所有元素都需要移动一个位置,因此需要的时间为 O(N)。
python_effect_0.png

可以看出以上的性能对比还是比较明显的。

那么很自然的问题是,如果我们有一个需求是频繁的从队列的头部和尾部修改元素,那么我们应该用什么呢?deque是一个不错的选择,除 pop 和 append 外,双端队列还暴露了方法 popleft 和 appendleft,它们的运行时间 都是 0(1)。
python_effect_1.png

虽然双端队列有这些优点 , 但在大多数情况下,都不应用它来替换常规列表。 方法 appendleft 和 popleft 的高效是要付出代价的 : 访问双端队列中间的元素所需的时间为 O(N),如下表所示。

python_effect_2.png

字典

字典是一个非常好的数据结构,保存的是k,v关系。并且在插入、 删除和访问元素方面的表现都非常杰出一-所有这些操作的时间复杂度都是 0(1)。

你是否遇到过这样的需求,给你一个list,让你统计list中每个元素出现的次数,这个时候你的写法应该是什么,用一个set或者dict,然后判断重复,如果重复就将这个val加1。这里我们提供了另一种方法,就是python提供的Counter方法。

from collections import Counter

def counter_dict(items):
    d = dict()
    for item in items:
        if d.get(item) is None:
            d[item] = 1
        else:
            d[item] += 1
    return d


a = [1, 2, 3, 4, 5, 1]
print counter_dict(a)

print Counter(a)

python_effect_3.png

然后我们能观察到,这个Counter的性能远远高于我们实现的函数,所以以后你是不是要使用更加简单高效的方法呢?

集合

集是一个无序 的元素集合 ,且其中的每个元素都必须是独一无二的 。 集的主要用途是成员资 格测试(检查集合中是否包含特定的元素),集操作包含井集、差集和交集 。

在 Python 中,集与字典一样,也是使用基于散列的算法实现的,因此其添加、删除等操作的时间复杂度都为 0(1),即不受集合规模的影响。

删除重复元素的时间复杂度为O(1)的,因为这种操作要求读取输入,并将每个不同的元素加入到集中 。 下面就标记着不同的集合操作对应的性能。
python_effect_4.png

堆是一种设计用于快速查找并提取集合中最大值或最小值的数据结构,其典型用途是按优先 级处理一系列任务 。

从理论上说,可结合使用有序列表和模块 bisect 中的工具来替代堆,这样提取最大值的时 间复杂度将为 0(1) (使用 list .pop ),但插入操作的时间复杂度仍为 O(N) (别忘了,虽然找出 插入位置的时间复杂度为 O(log(N) ),但在列表中间插入元素 的时间复杂度仍为 O(N) )。 堆是一 种效率更高 的数据结构 ,其元素插入操作和最大值提取操作的时间复杂度都为 O(log(N))。

在 Python 中,堆是通过对列表执行模块 heapq 中的函数来创建的 。 例如,如果有一个包含 10个元素的列 表, 可使用函数 heapq.heap工fy 将其转换为堆 。

import heapq

collection= [10, 3, 3, 4, 5, 6]
heapq.heapify(collection)
print collection

对堆执行插入和提取操作 ,可使用函数 heapq.heappush 和 heapq.heappop。 函数 heapq.heappop提取集合中的最小值,时间复杂度为 O(log(N)) .

# coding  python 
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×