комбинации между двумя списками?


это было некоторое время, и у меня возникли проблемы с обертыванием головы вокруг алгоритма, который я пытаюсь сделать. В принципе, у меня есть два списка и я хочу получить все комбинации двух списков.

Я не мог бы объяснить это правильно, так что вот пример.

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

выход в этом случае будет иметь вид:

1.  A1 B2
2.  B1 A2

хитрость заключается в том, что у меня может быть больше элементов в переменной "имя", чем элементы в переменной "число" (число всегда будет равно или меньше имя переменной).

Я запутался, как сделать все комбинации (вложенный цикл for?) и еще больше запутался в логике сдвига элементов в переменной name в том случае, если в имени больше элементов, чем в списке номеров.

Я не лучший программист, но думаю, что я могу дать ему шанс, если кто-то может помочь мне прояснить логику/алгоритм для достижения этой цели. Так что я просто застрял на вложенных для петли.

обновление:

вот результат с 3 переменными и 2 числами:

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

выход:

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

8 ответов:

предположим len(list1) >= len(list2). То, что вы, кажется, хотите, чтобы взять все перестановки длины len(list2) С list1 и сопоставить их с элементами из list2. В python:

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

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

возвращает

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

самый простой способ-это использовать itertools.product:

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

может быть проще, чем самый простой выше:

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

без какого-либо импорта

вы можете попробовать один список строк понимания:

>>> [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, чтобы сделать результат в виде плоского списка.

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

ссылка с этой ссылке

Я искал список, умноженный на себя только с уникальными комбинациями, которые предоставляются в качестве этой функции.

import itertools
itertools.combinations(list, n_times)

вот как отрывок из документы Python на itertools что может помочь вам найти то, что ищете.

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

без itertools

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

отвечая на вопрос "учитывая два списка, найдите все возможные перестановки пар одного элемента из каждого списка" и используя базовую функциональность Python (т. е. без itertools) и, следовательно, упрощая репликацию для других языков программирования:

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)

возвращает

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