点击关注我哦
欢迎关注 “小白玩转Python”,发现更多 “有趣”
本文绝对是一篇涉及技巧,代码优化,面试等Python问题的干货分享
Python 是初学者发现非常容易入门的语言之一。它是一个解释型、面向对象的和高级语言的。
在这篇文章中,我们将讨论面试中的问题,python 执行操作的技巧,如何优化代码等等。
那么,废话少说,让我们开始吧:
1) 优化和分析
我在采访中经常遇到这个问题——如何优化python代码?我通常更喜欢依靠标准的最佳实践(我将在后面的文章中讨论)尽早构建数据处理管道。然后,开始确定以下形式中可能存在的低效率:
一条语句 —— timeit(后面有多个例子)
代码的特定部分 —— cProfile
让我们首先学习代码分析。
什么是profile?
Profile是一组统计数据,用来描述程序各部分执行的频率和时间。
我们将看到如何使用标准库 cProfile 来评估给定 python 函数的profile文件。
让我们举一个斐波那契序列的例子来说明这个profile是什么样子的:
输出中的第一行显示了 calls 的总调用数量,其中有多少是 primitive calls。上述结果表明代码中存在递归(因为在180个 calls 中只有4个是 primitive)。
PyCallGraph 是分析代码的另一种方法,由于输出是 png 图形图像的形式,因此更容易解释。我们不会在这里讨论太多,因为它超出了这篇文章的范围,小伙伴有兴趣可以自己了解一下~
2) 用 decorator 缓存结果
继续上面关于优化的讨论,需要分析代码的运行时和内存配置文件。如果代码具有较长的运行时间和大量的内存使用,则称之为代价昂贵。
然后对应用程序进行分析,以确定有优化余地的代码。加速代码的典型方法是罪魁祸首——缓存。
Caching 的作用是存储计算开销很大的结果。因此,它们只需计算一次,通过作为 decorator 调用的包装器进行缓存和检索。
Decorator 是一个函数,其输入和输出也是一个函数。
3) join()组合字符串
字符串是不可变的。这意味着每次连接2个字符串时,由于无法在适当的位置进行修改,因此会创建一个新的表示。还要注意,字符串连接的时间度量是连接操作数和字符串平均长度的函数。
使用‘ join’连接字符串,因为它比‘ + ’运算符更快。
4) Counter
如果希望通过添加公共键的值来组合两个字典,则使用“ + ”操作符不起作用。
例如,a + b 在下面的代码中抛出错误,但是可以通过使用 Counter 来实现:
类似地,我们也可以找到 a 和 b 的交和并。
使用‘ Counter’的另一个非常基本的应用是,当我们传递一个字符串作为输入来计算字符串中每个字母的出现次数时,例如‘ python everyday’ :
可以使用 OrderedDict 来实现字典中出现的每个字母的顺序相同的计数:
计数器也可以用来计算字典中每个元素的出现次数,方法是将它展平:
5) 变量交换
避免为交换变量创建临时变量。为了通过一个例子来理解它,让我们看看表达式ー的交换是如何发生的:
x, y = y, x
X y = y x
第1步:首先计算右边的 y,x,它在内存中创建了一个2个元素的元组。这两个元素是用于 Python 内部寻址的 y 和 x 对象。
第2步:在计算左侧表达式期间,元组被分配到左侧,首先解压缩到 x,然后是 y,完成变量的交换。
6) list与deque
deque 是一个双向队列,支持从两端添加和删除元素。
list 插入到列表的末尾是有效的,但是,当一个新元素插入到列表的前面时,所有后续元素的索引都会向右移1。
在这里 deque 派上用场,这是更快,是一个双向链表。
7) ’ in’关键字
“ in”关键字是检查元素是否存在的最快和最干净的方法。
8) map,reduce,and filter 关键字
filter 可以输出一个包含满足给定条件的元素的新列表。
在下面的例子中,map 对象用于将给定的函数——一个指数函数转换为指定的迭代中的每个项。
通过将该函数应用于迭代器,reduce 返回单个值。将其标记为 reduce,因为它将迭代中的元素减少为单个累积值。
9) generator的使用
为了理解 generator,首先让我们理解迭代。例如,逐个读取一个列表的元素称为迭代,其中列表是可迭代的。但是迭代的问题在于,它将所有的值存储在内存中,而这些值可能并不是一直都需要的,因此 generator 的角色就产生了。
生成器是迭代器的一个子类型,它可以动态地生成值。这将节省内存并提高性能。
例如,在视频流中记录入室盗窃的情况,人们对每一张图片都不感兴趣,只对可能发生入室盗窃的图片感兴趣。因此,就像在正在进行的过程中,只需要分析某个与事件相关的信息,而不需要预先存储整个输入。
也可能是这样的情况,我们最初生成一个数字列表,但基于算法,只使用了少数元素。这导致了在生成这些数字时 CPU 周期的浪费。不仅如此,还要使用大量内存并发地将这些数字存储在对象中。
10)更多关于提高代码效率的提示,不言而喻
Python 检索局部变量要比检索全局变量快。每次需要全局对象时,访问全局对象都会通过一次完整的查找来运行,从而使其变慢;
list comprehension 更快,因为它不需要加载 append 并将其作为函数调用。查找、加载和函数调用是一个耗费时间的过程,这个过程可以通过迭代累加起来;
除了“if else”之外,尝试使用“try except”
交集 vs‘ & ’操作符
Unpacking 操作
而且,还有更多。正如他们所说,学习是永无止境的。我们将继续分享更多有关Python的文章。
在那之前,继续你的旅程,成为一个狂热的“Pythonista”。
· END ·
HAPPY LIFE