📜  Python代码的优化技巧

📅  最后修改于: 2020-05-03 13:22:30             🧑  作者: Mango

在本文中,讨论了一些有关更快 Python 代码的有趣的优化技巧。 这些技术有助于在Python代码中更快地产生结果。

  1. 使用内置函数和库:内置函数map()是用C代码实现的。 因此,解释器不必执行循环,因此可以大大提高速度。
    map()函数将函数应用于iterable的每个成员,并返回结果。 如果有多个参数,则map()返回一个包含元组的列表,该元组包含所有可迭代对象中的对应项。
    # Python程序演示库函数,使用map()示例节省编码时的时间
      import time
     # 较慢(没有map())
      start = time.clock()
      s = '芒果'
      U = []
      for c in s:
         U.append(c.upper())
      print U
      elapsed = time.clock()
      e1 = elapsed - start
      print "在函数上花费的时间是: " , e1
     # 更快(使用内置函数map())
      s = '芒果'
      start = time.clock()
      U = map ( str .upper, s)
      print U
      elapsed = time.clock()
      e2 = elapsed - start
      print "内置函数花费的时间为: " , e2

    输出:

    ['G', 'E', 'E', 'K', 'S']
    在函数上花费的时间是:  0.0394747945637
    ['G', 'E', 'E', 'K', 'S']
    内置函数花费的时间为:  0.0212335531192

    这些软件包是特定于平台的,这意味着我们需要适合所用平台的软件包。如果我们正在执行字符串操作,请考虑使用现有的模块“集合”(例如deque),该模块已针对我们的目的进行了高度优化。

    # Python程序说明了如何在两端插入带有快速追加和弹出键的类似列表的容器
    from collections import deque
    s = '芒果'
    # 制作新的双端队列
    d = deque(s)
    # 在右侧添加一个新条目
    d.append('y')
    # 在左侧添加新条目
    d.appendleft('h')
    print d
    d.pop() # return and remove the rightmost item
    d.popleft() # return and remove the lefttmost item
    # 反向打印列表双端队列
    print list(reversed(d))

    输出:

    deque(['h', 'g', 'e', 'e', 'k', 'y'])
    ['k', 'e', 'e', 'g']
# 导入迭代工具
import itertools
iter = itertools.permutations([1,2,3])
print list(iter)

输出:

[(1, 2, 3), (1, 3, 2), (2, 1, 3), (2, 3, 1), (3, 1, 2), (3, 2, 1)]

2,使用键进行排序:在Python中,我们应该改用内置排序的key参数,这是一种更快的排序方式。

# Python程序说明使用键进行排序
somelist = [1, -3, 6, 11, 5]
somelist.sort()
print somelist
s = '芒果'
# 如果您不想就地排序,请使用sorted():
s = sorted(s)
print s

输出:

[-3、1、5、6、11]
['e','e','g','k','s']

在每种情况下,列表都是根据您选择作为key参数一部分的索引进行排序的。这种方法对字符串和数字都适用。

3,优化循环:编写惯用代码:这听起来有些违反直觉,但是编写惯用代码将在大多数情况下使您的代码更快。这是因为Python被设计为只有一种显而易见/正确的方式来完成一项任务。
例如(字符串串联):

# Python程序说明如何使用优化的循环来更快地编码慢O(n ^ 2)-(注:在最新实现中,它是O(n))
s = 'hello芒果'
slist = ''
for i in s:
    slist = slist + i
print slist
# 字符串串联(惯用和快速O(n))
st = 'hello芒果'
slist = ''.join([i for i in s])
print slist
# 迭代范围的更好方法
evens = [ i for i in xrange(10) if i%2 == 0]
print evens
# 不太快
i = 0
evens = []
while i < 10:
    if i %2 == 0: evens.append(i)
        i += 1
print evens
# 慢
v = 'for'
s = '芒果 ' + v + ' 芒果'
print s
# fast
s = '芒果 %s 芒果' % v
print s

输出:

hello芒果
[0, 2, 4, 6, 8]
芒果 for 芒果

每次运行到s(i)的循环时,Python都会评估该方法。但是,如果将评估放在变量中,则该值是已知的,Python可以更快地执行任务。

4,尝试多种编码方法:每次创建应用程序时,都使用完全相同的编码方法几乎可以肯定会导致某些情况下应用程序的运行速度比实际运行速度慢。
例如(初始化字典元素)

# Python程序说明尝试多种编码方法以获得更快的结果
# 慢
mydict = {'g':1,'e':1,'e':1,'k':1}
word = '芒果文档'
for w in word:
    if w not in mydict:
        mydict[w] = 0
    mydict[w] += 1
print mydict
# 快
mydict = {'g':1,'e':1,'e':1,'k':1}
word = '芒果文档'
for w in word:
    try:
        mydict[w] += 1
    except KeyError:
        mydict[w] = 1
print mydict

输出:

{'e': 5, 'g': 3, 'f': 1, 'k': 3, 'o': 1, 's': 2, 'r': 1}

在两种情况下,输出都是相同的。唯一的区别是如何获得输出。

5,使用xrange代替range: range()将返回使用range()函数创建的数字列表。
xrange():此函数返回生成器对象,该对象只能用于循环显示数字。根据需要仅显示特定范围,因此称为“惰性评估”。

# 慢
x = [i for i in range(0,10,2)]
print x
# 快
x = [i for i in xrange(0,10,2)]
print x

输出:

[1、3、5、7、9]

因为xrange()一次只会在一个序列中产生一个整数元素,所以可以节省系统内存。而range()则为您提供了完整的列表,这对于循环来说是不必要的开销。

6,使用Python多重赋值来交换变量:这在Python中是优雅且快速的。

# Python程序说明在一行中交换变量的
# 慢
x = 2
y = 5
temp = x
x = y
y = temp
print x,y
x,y = 3,5
# 快
x, y = y, x
print x,y

输出:

5 2
5 3

7,尽可能使用局部变量: Python检索局部变量比检索全局变量更快。也就是说,避免使用“ global”关键字。因此,如果您打算经常(在循环内)访问方法,请考虑将其写入变量。

# Python程序说明如何尝试使用局部变量来使代码运行更快 快
class Test:
    def func(self,x):
        print x+x
# 声明分配类方法对象的变量
Obj = Test()
mytest = Obj.func # Declaring local variable
n = 2
for i in range(n):
    mytest(i) # 快 than Obj.func(i)

输出:

0
2