关于python:两个列表之间的组合?

combinations between two lists?

已经有一段时间了,我很难用我正在尝试的算法来概括我的想法。基本上,我有两个列表,想要得到这两个列表的所有组合。

我可能解释不正确,所以这里举个例子。

1
2
name = 'a', 'b'
number = 1, 2

在这种情况下,输出将是:

1
2
1.  A1 B2
2.  B1 A2

棘手的部分是,我可能在"name"变量中的项目比"number"变量中的项目多(数字总是等于或小于name变量)。

我很困惑如何进行所有组合(嵌套for循环?)如果名称中的项目比数字列表中的项目多,则在转换名称变量中的项目的逻辑上会更加混乱。

我不是最好的程序员,但如果有人能帮助我澄清逻辑/算法来实现这一点,我想我可以试一试。所以我被困在嵌套for循环上。

更新:

下面是3个变量和2个数字的输出:

1
2
name = 'a', 'b', 'c'
number = 1, 2

输出:

1
2
3
4
5
6
1.  A1 B2
2.  B1 A2
3.  A1 C2
4.  C1 A2
5.  B1 C2
6.  C1 B2


最简单的方法是使用itertools.product

1
2
3
4
a = ["foo","melon"]
b = [True, False]
c = list(itertools.product(a, b))
>> [("foo", True), ("foo", False), ("melon", True), ("melon", False)]


可能比上面最简单的简单:

1
2
3
4
>>> a = ["foo","bar"]
>>> b = [1, 2, 3]
>>> [(x,y) for x in a for y in b]
[('foo', 1), ('foo', 2), ('foo', 3), ('bar', 1), ('bar', 2), ('bar', 3)]

没有任何导入


假设len(list1) >= len(list2)。那么你想要的是从list1中获取长度为len(list2)的所有排列,并将它们与清单2中的项目匹配。在python中:

1
2
3
4
5
import itertools
list1=['a','b','c']
list2=[1,2]

[zip(x,list2) for x in itertools.permutations(list1,len(list2))]

退换商品

1
[[('a', 1), ('b', 2)], [('a', 1), ('c', 2)], [('b', 1), ('a', 2)], [('b', 1), ('c', 2)], [('c', 1), ('a', 2)], [('c', 1), ('b', 2)]]


我在寻找一个列表,它本身与唯一的组合相乘,作为这个函数提供。

1
2
import itertools
itertools.combinations(list, n_times)

这里是从itertools上的python文档中摘录的,这可能有助于您找到所需的内容。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Combinatoric generators:

Iterator                                 | Results
-----------------------------------------+----------------------------------------
product(p, q, ... [repeat=1])            | cartesian product, equivalent to a
                                         |   nested for-loop
-----------------------------------------+----------------------------------------
permutations(p[, r])                     | r-length tuples, all possible
                                         |   orderings, no repeated elements
-----------------------------------------+----------------------------------------
combinations(p, r)                       | r-length tuples, in sorted order, no
                                         |   repeated elements
-----------------------------------------+----------------------------------------
combinations_with_replacement(p, r)      | r-length tuples, in sorted order,
                                         | with repeated elements
-----------------------------------------+----------------------------------------
product('ABCD', repeat=2)                | AA AB AC AD BA BB BC BD CA CB CC CD DA DB DC DD
permutations('ABCD', 2)                  | AB AC AD BA BC BD CA CB CD DA DB DC
combinations('ABCD', 2)                  | AB AC AD BC BD CD
combinations_with_replacement('ABCD', 2) | AA AB AC AD BB BC BD CC CD DD

您可能想尝试一个单行列表理解:

1
2
3
4
>>> [name+number for name in 'ab' for number in '12']
['a1', 'a2', 'b1', 'b2']
>>> [name+number for name in 'abc' for number in '12']
['a1', 'a2', 'b1', 'b2', 'c1', 'c2']


Interjay对答案的微小改进,使结果成为一个扁平的列表。

1
2
3
4
5
>>> list3 = [zip(x,list2) for x in itertools.permutations(list1,len(list2))]
>>> import itertools
>>> chain = itertools.chain(*list3)
>>> list4 = list(chain)
[('a', 1), ('b', 2), ('a', 1), ('c', 2), ('b', 1), ('a', 2), ('b', 1), ('c', 2), ('c', 1), ('a', 2), ('c', 1), ('b', 2)]

来自此链接的引用


回答问题"给定两个列表,从每个列表中查找一个项目对的所有可能排列",并使用基本的python功能(即,不使用itertools),因此,可以很容易地为其他编程语言复制:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
def rec(a, b, ll, size):
    ret = []
    for i,e in enumerate(a):
        for j,f in enumerate(b):
            l = [e+f]
            new_l = rec(a[i+1:], b[:j]+b[j+1:], ll, size)
            if not new_l:
                ret.append(l)
            for k in new_l:
                l_k = l + k
                ret.append(l_k)
                if len(l_k) == size:
                    ll.append(l_k)
    return ret

a = ['a','b','c']
b = ['1','2']
ll = []
rec(a,b,ll, min(len(a),len(b)))
print(ll)

退换商品

1
[['a1', 'b2'], ['a1', 'c2'], ['a2', 'b1'], ['a2', 'c1'], ['b1', 'c2'], ['b2', 'c1']]


没有Itertools

1
[(list1[i], list2[j]) for i in xrange(len(list1)) for j in xrange(len(list2))]