据我所知,有三种通过理解创建生成器的方法1.
经典之一:
def f1():
g = (i for i in range(10))
Run Code Online (Sandbox Code Playgroud)
该yield变种:
def f2():
g = [(yield i) for i in range(10)]
Run Code Online (Sandbox Code Playgroud)
的yield from变体(即提出了SyntaxError除了一个函数的内部):
def f3():
g = [(yield from range(10))]
Run Code Online (Sandbox Code Playgroud)
这三种变体导致不同的字节码,这并不奇怪.第一个是最好的,这似乎是合乎逻辑的,因为它是通过理解创建生成器的专用,直接的语法.但是,它不是产生最短字节码的那个.
在Python 3.6中反汇编
经典的发电机理解
>>> dis.dis(f1)
4 0 LOAD_CONST 1 (<code object <genexpr> at...>)
2 LOAD_CONST 2 ('f1.<locals>.<genexpr>')
4 MAKE_FUNCTION 0
6 LOAD_GLOBAL 0 (range)
8 LOAD_CONST 3 (10)
10 CALL_FUNCTION 1
12 GET_ITER
14 CALL_FUNCTION 1
16 STORE_FAST 0 (g) …Run Code Online (Sandbox Code Playgroud) 我有一个从列表列表返回列表的函数,其中返回列表按索引号对每个列表的成员进行分组。代码和示例:
def listjoinervar(*lists: list) -> list:
"""returns list of grouped values from each list
keyword arguments:
lists: list of input lists
"""
assert(len(lists) > 0) and (all(len(i) == len(lists[0]) for i in lists))
joinedlist = [None] * len(lists) * len(lists[0])
for i in range(0, len(joinedlist), len(lists)):
for j in range(0, len(lists[0])):
joinedlist[i//len(lists[0]) + j*len(lists[0])] = lists[i//len(lists[0])][j]
return joinedlist
a = ['a', 'b', 'c']
b = [1, 2, 3]
c = [True, False, False]
listjoinervar(a, b, c)
# ['a', 1, True, …Run Code Online (Sandbox Code Playgroud)