写代码跟写作类似,需要不断地练习,不断地阅读,获得灵感,然后反复修改(重构)。写代码有代码补全工具,然后我们还是需要不断地练习、实验自己的新想法。
之前对python的推导式没有仔细去了解,今天抽空练习了下,顺路重构下以前代码里比较耗时的逻辑。以下为正文,分享给大家:
推导式comprehensions(又称解析式)。推导式是可以从一个数据序列构建另一个新的数据序列的结构体。 常用的比如列表推导式、字典推导式。
01
列表推导式
代替for循环处理list,而且速度还快很多。对比下for循环跟[ ]的方式,代码如下:
import time
t1=time.time()
z=[]
for i in range(100000):
if i%2==0:
j=i+3
z.append(j)
t2=time.time()
print(t2-t1)
t1=time.time()
z=[i+3 for i in range(100000) if i%2==0]
t2=time.time()
print(t2-t1)
除了从耗时上评估性能之外,还可以通过dis模块获取到对应的
字节码指令
来评估。何为字节码指令?
指的是由一个字节长度的、代表着某种特定含义的数字(操作码,Opcode)以及跟随其后的零至多个代表此操作所需参数(操作数,Operands)而构成。
先来用代码实现下:
import dis
def f1():
z=[]
for i in range(10000):
if i%2==0:
j=i+3
z.append(j)
def f2():
z=[i+3 for i in range(10000) if i%2==0]
dis.dis(f1)
dis输出的字节码如下:
4 0 BUILD_LIST 0
2 STORE_FAST 0 (z)
5 4 SETUP_LOOP 46 (to 52)
6 LOAD_GLOBAL 0 (range)
8 LOAD_CONST 1 (10000)
10 CALL_FUNCTION 1
12 GET_ITER
>> 14 FOR_ITER 34 (to 50)
16 STORE_FAST 1 (i)
6 18 LOAD_FAST 1 (i)
20 LOAD_CONST 2 (2)
22 BINARY_MODULO
24 LOAD_CONST 3 (0)
26 COMPARE_OP 2 (==)
28 POP_JUMP_IF_FALSE 14
7 30 LOAD_FAST 1 (i)
32 LOAD_CONST 4 (3)
34 BINARY_ADD
36 STORE_FAST 2 (j)
8 38 LOAD_FAST 0 (z)
40 LOAD_ATTR 1 (append)
42 LOAD_FAST 2 (j)
44 CALL_FUNCTION 1
46 POP_TOP
48 JUMP_ABSOLUTE 14
>> 50 POP_BLOCK
>> 52 LOAD_CONST 0 (None)
54 RETURN_VALUE
同样,也对列表推导式,输出字节码:
def f2():
z=[i+3 for i in range(10000) if i%2==0]
dis.dis(f2)
对比下方的字节码跟上文的f1的字节码长度,f2在操作步骤上就少很多。
10 0 LOAD_CONST 1 (<code object <listcomp> at 0x10bb6c420)
2 LOAD_CONST 2 ('f2.<locals>.<listcomp>')
4 MAKE_FUNCTION 0
6 LOAD_GLOBAL 0 (range)
8 LOAD_CONST 3 (10000)
10 CALL_FUNCTION 1
12 GET_ITER
14 CALL_FUNCTION 1
16 STORE_FAST 0 (z)
18 LOAD_CONST 0 (None)
20 RETURN_VALUE
02
字典推导式
可以方便的用来交换键名与键值,如下:
mix = {'m': 300, 'i': 500,'x':1000}
lab = {v: k for k,v in mix.items()}
print(lab)
# {300:"m",500:"i",1000:"x"}
03
推荐2个在线学习的网站
HackerRank
为程序员们提供一个以编码谜题和现实生活中遇到的编码难题为基础的新兴的社交平台。
5 million developers.
codepen
是一个完全免费的前端代码托管服务,上面有很多特效代码,也是我常逛的~
欢迎留言~补充你常逛的技术网站~