python代码优化_Python 代码优化技巧(一)

代码优化Part1

分享最近看到的关于代码优化的一些技巧。

if 判断的短路特性

对于and,应该把满足条件少的放在前面,这样当对于大量判断时, 满足条件少的情况直接回导致其后其他表达式不会计算从而节约时间(因为 False and True 还是 False)import timeit

s1 = """

a = range(2000)

[i for i in a if i % 2 ==0 and i > 1900]

"""

s2 = """

a = range(2000)

[i for i in a if i > 1900 and i % 2 ==0]

"""

print timeit.timeit(stmt=s1, number=1000)

print timeit.timeit(stmt=s2, number=1000)

运行结果如下:➜ python test6.py

0.248532056808

0.195827960968

# 可以看到s2 表达式计算更快, 因为大部分情况都不满足 i>1900, 所以这些情况下, i % 2 == 0 也没有计算,从而节约了时间

同理对于or,把满足条件多的放在前面。import timeit

s1 = """

a = range(2000)

[i for i in a if 10 < i <20 or 1000 < i < 2000]

"""

s2 = """

a = range(2000)

[i for i in a if 1000 < i < 2000 or 10 < i <20]

"""

print timeit.timeit(stmt=s1, number=1000)

print timeit.timeit(stmt=s2, number=1000)

运行结果:0.253124952316

0.202992200851

join 合并字符串

join 合并字符串比循环使用 + 来合并要快。import timeit

s1 = """

a = [str(x) for x in range(2000)]

s = ''

for i in a:

s += i

"""

s2 = """

a = [str(x) for x in range(2000)]

s = ''.join(a)

"""

print timeit.timeit(stmt=s1, number=1000)

print timeit.timeit(stmt=s2, number=1000)

运行结果如下:python test6.py

0.558945894241

0.422435998917

while 1 和 while True

在python2.x里, True 和 False 不是保留的关键字,是一个全局变量,这意味着你可以这样>>> True = 0

>>> True

0

>>> if not True:

... print '1'

...

1

所以下面这两种情况:import timeit

s1 = """

n = 1000000

while 1:

n -= 1

if n <= 0: break

"""

s2 = """

n = 1000000

while True:

n -= 1

if n <= 0: break

"""

print timeit.timeit(stmt=s1, number=100)

print timeit.timeit(stmt=s2, number=100)

运行结果如下:➜ python test6.py

5.18007302284

6.84624099731

因为每次判断 while True 的时候, 先要去找到True的值。

在python3.x里, True 变成了关键字参数,所以上述两种情况就一样了。

cProfile, cStringIO 和 cPickle

使用C语言的版本写的扩展要比原生的要快。cPickle vs pickle 如下:import timeit

s1 = """

import cPickle

import pickle

n = range(10000)

cPickle.dumps(n)

"""

s2 = """

import cPickle

import pickle

n = range(10000)

pickle.dumps(n)

"""

print timeit.timeit(stmt=s1, number=100)

print timeit.timeit(stmt=s2, number=100)

运行结果如下:➜ python test6.py

0.182178974152

1.70917797089

合理使用生成器

区别

使用()得到的是一个generator对象,所需要的内存空间与列表的大小无关,所以效率会高一些。import timeit

s1 = """

[i for i in range (100000)]

"""

s2 = """

(i for i in range(100000))

"""

print timeit.timeit(stmt=s1, number=1000)

print timeit.timeit(stmt=s2, number=1000)

结果:➜ python test6.py

5.44327497482

0.923446893692

但是对于需要循环遍历的情况:使用迭代器效率反而不高,如下:import timeit

s1 = """

ls = range(1000000)

def yield_func(ls):

for i in ls:

yield i+1

for x in yield_func(ls):

pass

"""

s2 = """

ls = range(1000000)

def not_yield_func(ls):

return [i+1 for i in ls]

for x in not_yield_func(ls):

pass

"""

print timeit.timeit(stmt=s1, number=10)

print timeit.timeit(stmt=s2, number=10)

结果如下:➜ python test6.py

1.03186702728

1.01472687721

所以使用生成器是一个权衡的结果,对于内存、速度综合考虑的结果。

xrange

在python2.x里xrange 是纯C实现的生成器,相对于range来说,它不会一次性计算出所有值在内存中。但它的限制是只能和整型一起工作:你不能使用long或者float。

import 语句的开销

import语句有时候为了限制它们的作用范围或者节省初始化时间,被卸载函数内部,虽然python的解释器不会重复import同一个模块不会出错,但重复导入会影响部分性能。

有时候为了实现懒加载(即使用的时候再加载一个开销很大的模块),可以这么做:email = None

def parse_email():

global email

if email is None:

import email

...

# 这样一来email模块仅会被引入一次,在parse_email()被第一次调用的时候。

参考资源:https://wiki.python.org/moin/...

http://blog.csdn.net/zhoudaxi...

https://www.ibm.com/developer...

NEXT ctypes

学习人工智能,机器学习都离不开数学基础和编程知识。无论你是数据科学的初学者还是已经从事人工智能开发的有经验人员,这门课都适合于你。为什么这么说?首先人工智能和机器学习本质上就是算法,而算法就是数学及统计学以及编程的结合。当前市场上有许多开源的软件包如SKLEARN确实可以帮助没经验的或缺乏数学或算法基础的人实现机器学习模型及预测,但这些工具无法使你真正懂得算法的本质或来源,或者无法使你在不同场合下灵活运用及改进算法。记住,在实际工作中找到适合应用场景的解决方案是最难但是最重要的。但这离不开数学基础和算法理解。比如,线性回归是一类普遍的机器学习算法,所有的机器学习软件都有现成的方法实现模型,但如果在训练数据中加入几条新数据,那么新建立的模型和原来的模型有和联系或不同?再比如,为什么深度神经网络中的Sigmoid函数一般只用到输出层?神经网络的向后传播理论如何与泰勒展开和复合函数的偏导数联系在一起?人工智能中推荐系统和文字向量如何与矩阵的奇异分解以及特征向量联系?模型中对标签进行数据变换如何影响预测值?所有这些问题的答案,你都可以从本课中找到线索。本课系统地讲述了有关人工智能,机器学习背后的数学知识。特别指出,微积分和代数知识是本课的核心。统计学基础被安排在另外的课程中。除此之外,我在每一章节或主要知识点后都安排了各类程序以解释和回顾所学到的东西。最后要提到的是,这不是一门工程项目实践课。但我会另外专门安排有关人工智能,机器学习的实践课程
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值