如何获取两个列表之间的所有映射?
我们有两个列表,A 和 B:
A = ['a','b','c']
B = [1, 2]
有没有一种简单的方法可以在 Python 中创建一个包含所有 A 和 B 之间映射的集合,这个集合的大小是 2 的 n 次方(这里 n 是 A 的长度,比如 2^3=8)?也就是说:
[(a,1), (b,1), (c,1)]
[(a,1), (b,1), (c,2)]
[(a,1), (b,2), (c,1)]
[(a,1), (b,2), (c,2)]
[(a,2), (b,1), (c,1)]
[(a,2), (b,1), (c,2)]
[(a,2), (b,2), (c,1)]
[(a,2), (b,2), (c,2)]
使用 itertools.product
,我们可以得到所有的元组:
import itertools as it
P = it.product(A, B)
[p for p in P]
这会得到:
Out[3]: [('a', 1), ('a', 2), ('b', 1), ('b', 2), ('c', 1), ('c', 2)]
2 个回答
11
import itertools as it
A = ['a','b','c']
B = [1, 2]
for i in it.product(*([B]*len(A))):
print(list(zip(A, i)))
输出:
[('a', 1), ('b', 1), ('c', 1)]
[('a', 1), ('b', 1), ('c', 2)]
[('a', 1), ('b', 2), ('c', 1)]
[('a', 1), ('b', 2), ('c', 2)]
[('a', 2), ('b', 1), ('c', 1)]
[('a', 2), ('b', 1), ('c', 2)]
[('a', 2), ('b', 2), ('c', 1)]
[('a', 2), ('b', 2), ('c', 2)]
不太确定这是否算是很“Python风格”,如果你看看 it.product(*([B]*len(A)))
,它确实使用了很多Python特有的语言特性。不过,这样写其实有点难懂,不太符合Python的简洁风格……这里的B是根据A的长度重复了n次,然后传递给了product函数。
26
你可以使用 itertools.product
和 zip
来实现这个功能。
from itertools import product
print [zip(A, item) for item in product(B, repeat=len(A))]
输出结果
[[('a', 1), ('b', 1), ('c', 1)],
[('a', 1), ('b', 1), ('c', 2)],
[('a', 1), ('b', 2), ('c', 1)],
[('a', 1), ('b', 2), ('c', 2)],
[('a', 2), ('b', 1), ('c', 1)],
[('a', 2), ('b', 1), ('c', 2)],
[('a', 2), ('b', 2), ('c', 1)],
[('a', 2), ('b', 2), ('c', 2)]]
product(B, repeat=len(A))
会生成
[(1, 1, 1),
(1, 1, 2),
(1, 2, 1),
(1, 2, 2),
(2, 1, 1),
(2, 1, 2),
(2, 2, 1),
(2, 2, 2)]
然后我们从这个生成的结果中取出每一个元素,并用 A
来配对,这样就能得到你想要的输出了。