使用列表推导式的嵌套循环

114

如果我有两个字符串,'abc''def',我可以使用两个for循环来获取它们的所有组合:

for j in s1:
  for k in s2:
    print(j, k)

不过,我希望能够使用列表推导式来完成这个任务。我尝试了很多种方法,但从未成功过。有没有人知道如何做到这一点?

4个回答

174
lst = [j + k for j in s1 for k in s2]
或。
lst = [(j, k) for j in s1 for k in s2]

如果您想要元组。

就像问题中所述,for j...是外循环,for k...是内循环。

基本上,在列表推导式中,您可以通过将一个 'for x in y' 子句紧接在另一个后面来拥有任意数量的独立子句。

为使其更易读,请使用多行:

lst = [
       j + k         # result
       for j in s1   # for loop 
         for k in s2 # for loop
                     # condition   
       ]

3
如果您想要使用嵌套循环来迭代一个嵌套的列表,该怎么办呢? 类似这样:[print('a') for ax in axs for axs in axes] 会打印出一堆 [None, None...] 直到 axes 列表的长度。 - Pablo Ruiz Ruiz
@Pablo,我认为你的循环顺序反了。L1 = [[[e1, e2, ...], ...], ...] -> [ e for L2 in L1 for L3 in L2 for e in L3 ] - AnOccasionalCashew
1
for语句的顺序与将其写为两个独立行的for循环相同。 - user3064538
我可以在以下使用条件语句吗? - Salik Malik
lst = [j+k if BLAHBLAHBLAH for j in s1 for k in s2] 或者类似的内容 - Salik Malik
这种行为相当出乎意料。我更喜欢for k(后者)成为外层循环,这与数学约定/自然语言一致。 - Shen Zhuoran

43

由于本质上这是一个笛卡尔积,因此您也可以使用itertools.product。我认为这更清晰,尤其是当您有更多的输入可迭代对象时。

itertools.product('abc', 'def', 'ghi')

笛卡尔积只是@aaronasterling提供的更一般答案的一个子集,其中内部循环值可以是每个外部循环值的函数。例如:对于x在范围(5)中,对于y在范围(x)中。 - jpcgt

1
这只是@miles82答案的即用版本(请归功于原作者)。
from itertools import product
list(map(list, product('abc', 'def') ))

输出:

[['a', 'd'],
 ['a', 'e'],
 ['a', 'f'],
 ['b', 'd'],
 ['b', 'e'],
 ['b', 'f'],
 ['c', 'd'],
 ['c', 'e'],
 ['c', 'f']]


如果你想知道为什么我们需要“list(map(list” - itertools.product返回一个迭代器。

0

也尝试使用递归:

s=""
s1="abc"
s2="def"
def combinations(s,l):
    if l==0:
        print s
    else:
        combinations(s+s1[len(s1)-l],l-1)
        combinations(s+s2[len(s2)-l],l-1)

combinations(s,len(s1))

提供给您8种组合:

abc
abf
aec
aef
dbc
dbf
dec
def

根据OP的问题,我认为输出应该给出几个字母对,并且应该有9种组合。 - Mattia
1
关于:abd,abe,acd,ace,acf,adb,adc,ade,adf,aeb,aed,afb,afc,afd,afe以及所有以c、e或f开头的内容发生了什么?即使顺序不重要,也省略了:bda,ade等。 - Harry Binswanger
这个工作原理是,最左边的位置只能是"a"或"d",中间的位置只能是"b"或"e",右边的位置只能是"c"或"f"。 - Stefan Gruenwald

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接