我正在尝试做
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,因此请使用 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)
。关于python - 如何用两个 'for' 枚举列表理解?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51304270/