python – 如何使用两个’for’来枚举列表推导?

我想做

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)]

但是,当有两个人时,我无法弄清楚如何干净利落地做到这一点.我以前找不到这个问题.

最佳答案
您正在两个列表上创建一个Cartesian product,因此请使用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))]

对于无法使用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]

毕竟,实质上枚举(iterable,start = 0)相当于zip(itertools.count(start),iterable).

转载注明原文:python – 如何使用两个’for’来枚举列表推导? - 代码日志