如何在列表推导中修改外部变量?
Python代码:
i: int = 1
table: list = [[i, bit, None, None] for bit in h]
预期的行为:每次循环中,i
的值需要增加1。
伪代码:
i: int = 1
table: list = [[i++, bit, None, None] for bit in h]
3 个回答
0
获取结果的更多方法:
[[i, bit, None, None]
for i in [0]
for bit in h
for i in [i+1]]
[a[:]
for a in [[None] * 4]
for a[:2] in enumerate(h, start=1)]
[[*tpl]
for nones in [repeat(None)]
for tpl in zip(count(1), h, nones, nones)]
[*map(list, zip(count(1), h, nones := repeat(None), nones))]
基准测试,目前无法运行 :-(
import timeit
setup = '''
from itertools import count, repeat
h = '10010010'
'''
codes = [
'lst = [[i, bit, None, None ] for i, bit in enumerate(h, start=1)]',
'i=0; lst = [[i:=i+1, bit, None, None] for bit in h]',
'lst = [[i, bit, None, None] for i in [0] for bit in h for i in [i+1]]',
'lst = [a[:] for a in [[None] * 4] for a[:2] in enumerate(h, start=1)]',
'lst = [[*tpl] for nones in [repeat(None)] for tpl in zip(count(1), h, nones, nones)]',
'lst = [*map(list, zip(count(1), h, nones := repeat(None), nones))]',
]
exec(setup)
for code in codes:
exec(code)
print(lst)
del lst
setup = '''
from itertools import count, repeat
h = '10010010' * 1000
'''
for code in codes:
t = min(timeit.repeat(code, setup, number=10, repeat=25)) / 10
print(f'{t * 1e3:4.2f} ms ', code)
4
作为一个思考实验,这就是你问题的直接答案:
>>> i=0
>>> [[i:=i+1, bit, None, None] for bit in h]
[[1, '1', None, None], [2, '0', None, None], [3, '0', None, None], [4, '1', None, None], [5, '0', None, None], [6, '0', None, None], [7, '1', None, None], [8, '0', None, None]]
你绝对不应该那样做,应该使用 enumerate
,这是大家公认的好方法。
6
列表推导式不应该用来处理外部的副作用。在这种情况下,应该使用 enumerate
,而不是依赖外部变量:
h = '10010010' # Undefined in OP example. Just something to enumerate.
table = [[i, bit, None, None ] for i, bit in enumerate(h, start=1)]
for row in table:
print(row)
输出结果:
[1, '1', None, None]
[2, '0', None, None]
[3, '0', None, None]
[4, '1', None, None]
[5, '0', None, None]
[6, '0', None, None]
[7, '1', None, None]
[8, '0', None, None]