【发布时间】:2014-07-17 16:26:17
【问题描述】:
我有几个列表,我需要对这些列表项的每个可能组合做一些事情。在两个列表的情况下,我可以这样做:
for a in alist:
for b in blist:
# do something with a and b
但是,如果有更多的列表,比如 6 或 7 个列表,这种方法似乎不太情愿。有什么方法可以优雅地实现这个迭代?
【问题讨论】:
我有几个列表,我需要对这些列表项的每个可能组合做一些事情。在两个列表的情况下,我可以这样做:
for a in alist:
for b in blist:
# do something with a and b
但是,如果有更多的列表,比如 6 或 7 个列表,这种方法似乎不太情愿。有什么方法可以优雅地实现这个迭代?
【问题讨论】:
您可以使用itertools.product 从您的列表中进行所有可能的组合。结果将是一个很长的tuple 列表,其中每个列表中的元素按照您传入列表的顺序排列。
>>> a = [1,2,3]
>>> b = ['a', 'b', 'c']
>>> c = [4,5,6]
>>> import itertools
>>> list(itertools.product(a,b,c))
[(1, 'a', 4), (1, 'a', 5), (1, 'a', 6), (1, 'b', 4), (1, 'b', 5), (1, 'b', 6), (1, 'c', 4), (1, 'c', 5), (1, 'c', 6),
(2, 'a', 4), (2, 'a', 5), (2, 'a', 6), (2, 'b', 4), (2, 'b', 5), (2, 'b', 6), (2, 'c', 4), (2, 'c', 5), (2, 'c', 6),
(3, 'a', 4), (3, 'a', 5), (3, 'a', 6), (3, 'b', 4), (3, 'b', 5), (3, 'b', 6), (3, 'c', 4), (3, 'c', 5), (3, 'c', 6)]
例如
for ai, bi, ci in itertools.product(a,b,c):
print ai, bi, ci
输出
1 a 4
1 a 5
1 a 6
... etc
【讨论】:
itertools.product(a,b,c) 作为 for 语句 expression_list 而不先从中创建新列表。
如果实际上有 6 或 7 个列表,则可能值得转到 itertools.product 以提高可读性。但是对于简单的情况,使用list comprehension 很简单,并且不需要导入。例如:
alist = [1, 2, 3]
blist = ['A', 'B', 'C']
clist = ['.', ',', '?']
abc = [(a,b,c) for a in alist for b in blist for c in clist]
for e in abc:
print("{}{}{} ".format(e[0],e[1],e[2])),
# 1A. 1A, 1A? 1B. 1B, 1B? 1C. 1C, 1C? 2A. 2A, 2A? 2B. 2B, 2B? 2C. 2C, 2C? 3A. 3A, 3A? 3B. 3B, 3B? 3C. 3C, 3C?
【讨论】: