sha*_*k3r 13 python generator set set-comprehension
Q1 - 以下是set()
a generator expression
还是a set comprehension
?(或者它们是否相同?如果是这样,那么list
&dict
comprehensions是否也在发电机上进行相应的类型转换?)
my_set = {x for x in range(10)}
Run Code Online (Sandbox Code Playgroud)
Q2 - 评估是否考虑重复值,然后通过应用删除它们set()
?
dup_set = {x for x in [0, 1, 2, 0, 1, 2]}
Run Code Online (Sandbox Code Playgroud)
理解是否比常规for
循环更好地执行(速度方面)?
更新 - 我尝试timeit
用于速度比较.我不确定我是否只是(公平).
C:\>python -m timeit "s = set()" "for x in range(10):" "
s.add(x)"
100000 loops, best of 3: 2.3 usec per loop
C:\>python -m timeit "s = {x for x in range(10)}"
1000000 loops, best of 3: 1.68 usec per loop
Run Code Online (Sandbox Code Playgroud)
现在,使用一些条件
C:\>python -m timeit "s = set()" "for x in range(10):" "
if x%2: s.add(x)"
100000 loops, best of 3: 2.27 usec per loop
C:\>python -m timeit "s = {x for x in range(10) if x%2}"
1000000 loops, best of 3: 1.83 usec per loop
Run Code Online (Sandbox Code Playgroud)
所以,有一些区别,是因为功能被硬编码c
?
Q1:是的,是的,是的,是的.或者至少他们表现得像这样.如果你看一下字节码,它会有点不同.让我们反汇编这段代码(Python 2.7):
def list_comp(l):
return [x+1 for x in l]
def dict_comp(l):
return {x+1:0 for x in l}
def set_comp(l):
return {x+1 for x in l}
def generator(l):
return (x+1 for x in l)
Run Code Online (Sandbox Code Playgroud)
这就是你得到的:
Disassembly of list_comp:
2 0 BUILD_LIST 0
3 LOAD_FAST 0 (l)
6 GET_ITER
>> 7 FOR_ITER 16 (to 26)
10 STORE_FAST 1 (x)
13 LOAD_FAST 1 (x)
16 LOAD_CONST 1 (1)
19 BINARY_ADD
20 LIST_APPEND 2
23 JUMP_ABSOLUTE 7
>> 26 RETURN_VALUE
Disassembly of dict_comp:
5 0 LOAD_CONST 1 (<code object <dictcomp> at 029DEE30)
3 MAKE_FUNCTION 0
6 LOAD_FAST 0 (l)
9 GET_ITER
10 CALL_FUNCTION 1
13 RETURN_VALUE
Disassembly of set_comp:
8 0 LOAD_CONST 1 (<code object <setcomp> at 029DECC8)
3 MAKE_FUNCTION 0
6 LOAD_FAST 0 (l)
9 GET_ITER
10 CALL_FUNCTION 1
13 RETURN_VALUE
Disassembly of generator:
11 0 LOAD_CONST 1 (<code object <genexpr> at 02A8FD58)
3 MAKE_FUNCTION 0
6 LOAD_FAST 0 (l)
9 GET_ITER
10 CALL_FUNCTION 1
13 RETURN_VALUE
Run Code Online (Sandbox Code Playgroud)
对于dict comprenhension,set comprehension和generator,字节码几乎不一样.它们都加载一个代码对象(<dictcomp>
,<setcomp>
或<genexpr>
),然后从中创建一个可调用的函数.列表理解是不同的,因为它生成对应于列表理解的字节码.这次它被解释,因此不是原生的.
Q2:它并不真正考虑重复值,因为它会使用您给出的列表创建一个理解.然后它通过理解创建集合.
关于时间:列表/字典/集合理解往往比其他任何事情都快.即使他们解释,产生的字节码的大多数情况下优化,如特殊字节码指令SET_ADD
,LIST_APPEND
或MAP_ADD
.
归档时间: |
|
查看次数: |
693 次 |
最近记录: |