I am trying to do
我想做
ls = [myfunc(a,b,i) for a in a_list for b in b_list]
but also pass in i
into myfunc, which is an index starting at 0 and incrementing for each new element.
但也将i传入myfunc,这是一个从0开始的索引,并为每个新元素递增。
For example:
例如:
a_list = 'abc'
b_list = 'def'
should result in
应该导致
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]
I know that I can use enumerate()
for just the normal case, ie.
我知道我可以使用enumerate()来表示正常情况,即。
ls = [myfunc(a,i) for a,i in enumerate(a_list)]
But I can't figure out how to do it cleanly when there are two for
s. I couldn't find this question posted previously either.
但是,当有两个人时,我无法弄清楚如何干净利落地做到这一点。我以前找不到这个问题。
3 个解决方案
#1
10
You are creating a Cartesian product over two lists, so use itertools.product()
instead of a double for
loop. This gives you a single iterable you can easily add enumerate()
to:
您正在两个列表上创建笛卡尔积,因此请使用itertools.product()而不是double for循环。这为您提供了一个可迭代的,您可以轻松地将enumerate()添加到:
from itertools import product
ls = [myfunc(a, b, i) for i, (a, b) in enumerate(product(a_list, b_list))]
For cases where you can't use product()
, you'd put the multiple loops in a generator expression, then add enumerate()
to that. Say you needed to filter some values of a_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)]
Another option is to add a separate counter; itertools.count()
gives you a counter object that produces a new value with next()
:
另一种选择是增加一个单独的柜台; 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]
After all, in essence enumerate(iterable, start=0)
is the equivalent of zip(itertools.count(start), iterable)
.
毕竟,实质上枚举(iterable,start = 0)相当于zip(itertools.count(start),iterable)。
#2
6
You can use enumerate on the sequence of pairs.
您可以在对序列上使用枚举。
ls = [myfunc(a,b,i) for (i,(a,b)) in
enumerate((a,b) for a in a_list for b in b_list)]
#3
2
For a simple nested loop, use itertools.product()
as @Martijn suggested.
对于一个简单的嵌套循环,请使用itertools.product()作为@Martijn建议。
If the expression is more complex you can use itertools.count
:
如果表达式更复杂,可以使用itertools.count:
i_gen = itertools.count()
ls = [myfunc(a, b, next(i_gen)) for a in a_list for b in b_list]
#1
10
You are creating a Cartesian product over two lists, so use itertools.product()
instead of a double for
loop. This gives you a single iterable you can easily add enumerate()
to:
您正在两个列表上创建笛卡尔积,因此请使用itertools.product()而不是double for循环。这为您提供了一个可迭代的,您可以轻松地将enumerate()添加到:
from itertools import product
ls = [myfunc(a, b, i) for i, (a, b) in enumerate(product(a_list, b_list))]
For cases where you can't use product()
, you'd put the multiple loops in a generator expression, then add enumerate()
to that. Say you needed to filter some values of a_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)]
Another option is to add a separate counter; itertools.count()
gives you a counter object that produces a new value with next()
:
另一种选择是增加一个单独的柜台; 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]
After all, in essence enumerate(iterable, start=0)
is the equivalent of zip(itertools.count(start), iterable)
.
毕竟,实质上枚举(iterable,start = 0)相当于zip(itertools.count(start),iterable)。
#2
6
You can use enumerate on the sequence of pairs.
您可以在对序列上使用枚举。
ls = [myfunc(a,b,i) for (i,(a,b)) in
enumerate((a,b) for a in a_list for b in b_list)]
#3
2
For a simple nested loop, use itertools.product()
as @Martijn suggested.
对于一个简单的嵌套循环,请使用itertools.product()作为@Martijn建议。
If the expression is more complex you can use itertools.count
:
如果表达式更复杂,可以使用itertools.count:
i_gen = itertools.count()
ls = [myfunc(a, b, next(i_gen)) for a in a_list for b in b_list]