如何用两个“for”枚举列表理解?
How do I enumerate a list comprehension with two 'for's?
我正在努力
ls = [myfunc(a,b,i) for a in a_list for b in b_list]
但也将 i
传入 myfunc,这是一个从 0 开始并为每个新元素递增的索引。
例如:
a_list = 'abc'
b_list = 'def'
应该导致
ls = [myfunc('a','d',0),
myfunc('a','e',1),
myfunc('a','f',2),
myfunc('b','d',3),
myfunc('b','e',4),
...
myfunc('c','f',8]
我知道我可以在正常情况下使用 enumerate()
,即
ls = [myfunc(a,i) for a,i in enumerate(a_list)]
但是当有两个 for
时,我不知道如何干净利落地做到这一点。我也找不到之前发布的这个问题。
您正在创建一个 Cartesian product over two lists, so use itertools.product()
而不是双 for
循环。这为您提供了一个可迭代对象,您可以轻松地将 enumerate()
添加到:
from itertools import product
ls = [myfunc(a, b, i) for i, (a, b) in enumerate(product(a_list, b_list))]
对于不能使用 product()
的情况,您可以将多个循环放在生成器表达式中,然后向其中添加 enumerate()
。假设您需要过滤 a_list
:
的某些值
gen = (a, b for a in a_list if some_filter(a) for b in b_list)
ls = [myfunc(a, b, i) for i, (a, b) in enumerate(gen)]
另一种选择是添加一个单独的计数器; itertools.count()
给你一个计数器对象,它产生一个新值 next()
:
from itertools import count
counter = count()
ls = [myfunc(a, b, next(counter))
for a in a_list if some_filter(a)
for b in b_list]
毕竟,本质上 enumerate(iterable, start=0)
等同于 zip(itertools.count(start), iterable)
。
您可以对对的序列使用枚举。
ls = [myfunc(a,b,i) for (i,(a,b)) in
enumerate((a,b) for a in a_list for b in b_list)]
对于简单的嵌套循环,按照@Martijn 的建议使用itertools.product()
。
如果表达式比较复杂你可以使用itertools.count
:
i_gen = itertools.count()
ls = [myfunc(a, b, next(i_gen)) for a in a_list for b in b_list]
我正在努力
ls = [myfunc(a,b,i) for a in a_list for b in b_list]
但也将 i
传入 myfunc,这是一个从 0 开始并为每个新元素递增的索引。
例如:
a_list = 'abc'
b_list = 'def'
应该导致
ls = [myfunc('a','d',0),
myfunc('a','e',1),
myfunc('a','f',2),
myfunc('b','d',3),
myfunc('b','e',4),
...
myfunc('c','f',8]
我知道我可以在正常情况下使用 enumerate()
,即
ls = [myfunc(a,i) for a,i in enumerate(a_list)]
但是当有两个 for
时,我不知道如何干净利落地做到这一点。我也找不到之前发布的这个问题。
您正在创建一个 Cartesian product over two lists, so use itertools.product()
而不是双 for
循环。这为您提供了一个可迭代对象,您可以轻松地将 enumerate()
添加到:
from itertools import product
ls = [myfunc(a, b, i) for i, (a, b) in enumerate(product(a_list, b_list))]
对于不能使用 product()
的情况,您可以将多个循环放在生成器表达式中,然后向其中添加 enumerate()
。假设您需要过滤 a_list
:
gen = (a, b for a in a_list if some_filter(a) for b in b_list)
ls = [myfunc(a, b, i) for i, (a, b) in enumerate(gen)]
另一种选择是添加一个单独的计数器; itertools.count()
给你一个计数器对象,它产生一个新值 next()
:
from itertools import count
counter = count()
ls = [myfunc(a, b, next(counter))
for a in a_list if some_filter(a)
for b in b_list]
毕竟,本质上 enumerate(iterable, start=0)
等同于 zip(itertools.count(start), iterable)
。
您可以对对的序列使用枚举。
ls = [myfunc(a,b,i) for (i,(a,b)) in
enumerate((a,b) for a in a_list for b in b_list)]
对于简单的嵌套循环,按照@Martijn 的建议使用itertools.product()
。
如果表达式比较复杂你可以使用itertools.count
:
i_gen = itertools.count()
ls = [myfunc(a, b, next(i_gen)) for a in a_list for b in b_list]