2016-09-15 4 views
2
import itertools 
a = [[2, 3], [3, 4]] 
b = [[5, 6], [7, 8], [9, 10]] 
c = [[11, 12], [13, 14]] 
d = [[15, 16], [17, 18]] 
e = [[12,16],[13,17],[14,18],[15,19]] 

q=[] 
q=list(itertools.combinations((a, b, b,c, c, d,e),7) 
print q 

Как бы я идти об использовании функции комбинации из itertools правильно использовать список один раз, а в 2 раза без замены, C 2 раза без замены, и d и е один раз каждый ?Создание комбинированных из списков с помощью itertools

[[[2, 3],[5, 6],[7, 8],[11, 12],[13, 14],[15, 16],[12,16]], 
[[2, 3],[5, 6],[7, 8],[11, 12],[13, 14],[15, 16],[13,17]], 
[[2, 3],[5, 6],[7, 8],[11, 12],[13, 14],[15, 16],[14,18]], 
[[2, 3],[5, 6],[7, 8],[11, 12],[13, 14],[15, 16],[15,19]], 
[[2, 3],[5, 6],[7, 8],[11, 12],[13, 14],[15, 16],[12,16]],... 
[[3, 4],[7, 8],[9, 10],[11, 12], [13, 14],[17, 18],[15,19]]] 
+1

являются два черпает из ' b' с заменой или без нее? –

+1

Я не уверен, что понимаю, что вы хотите здесь (можете ли вы дать первые несколько примеров выводов или что-то в этом уверен?), Но если вы закроете 'itertools.combinations' в' list' за приличное количество входов, вы почти гарантированно взорвать вашу память.Количество выходов растет примерно на уровне «O (n!)» (Факториальный рост); вы, как правило, ожидаете, чтобы повторять комбинации один за другим, а не хранить их сразу. – ShadowRanger

+0

Без замены, –

ответ

2

Похоже, вы ищете сочетание combinations и product: Используйте combinations, чтобы получить возможные комбинации без замены повторяющихся списков, а затем использовать product, чтобы объединить все эти комбинации. Вы можете поместить списки и подсчеты в два списка, zip этих списков и использовать выражение генератора для получения всех комбинаций.

from itertools import product, combinations, chain 
lists = [a,b,c,d,e] 
counts = [1,2,2,1,1] 
combs = product(*(combinations(l, c) for l, c in zip(lists, counts))) 

Для этого, например, combs генератора имеет 48 элементов, среди прочего:

[(([2, 3],), ([5, 6], [7, 8]), ([11, 12], [13, 14]), ([15, 16],), ([12, 16],)), 
... 
(([2, 3],), ([5, 6], [7, 8]), ([11, 12], [13, 14]), ([17, 18],), ([15, 19],)), 
(([2, 3],), ([5, 6], [9, 10]),([11, 12], [13, 14]), ([15, 16],), ([12, 16],)), 
... 
(([3, 4],), ([5, 6], [7, 8]), ([11, 12], [13, 14]), ([15, 16],), ([12, 16],)), 
... 
(([3, 4],), ([5, 6], [7, 8]), ([11, 12], [13, 14]), ([17, 18],), ([15, 19],)), 
... 
(([3, 4],), ([7, 8], [9, 10]),([11, 12], [13, 14]), ([17, 18],), ([15, 19],))] 

Если вы хотите flattened lists, просто chain им:

>>> combs = (list(chain(*p)) for p in product(*(combinations(l, c) for l, c in zip(lists, counts)))) 
>>> list(combs) 
[[[2, 3], [5, 6], [7, 8], [11, 12], [13, 14], [15, 16], [12, 16]], 
... 
[[3, 4], [7, 8], [9, 10], [11, 12], [13, 14], [17, 18], [15, 19]]] 
+0

спасибо, что это потрясающе –

1

Обновлено дано разъяснение ожидаемого выхода:

You want itertools.product:

itertools.product(a, b, b, c, c, c, c, d, e) 

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

Вы можете использовать расширенный аргумент распаковки, чтобы выразить повторения определенных аргументов немного более очевидно в Python 3:

itertools.product(a, *[b]*2, *[c]*4, d, e) 

Или использовать tobias_k's solution для более общего повторения последовательностей (которые также будут работать на py2).

+1

Но это не будет рисовать один из двух, от b и т. Д., Но всего 9 из всех. –

+1

@tobias_k: Я ответил, прежде чем ОП разъяснит точное использование. Починю. – ShadowRanger

1

Что ваше пытаются достичь это Cartesian product of input iterables, а не комбинации элемента, присутствующего в списке. Следовательно, вместо этого вы должны использовать itertools.product().

В случае повторения допускается из списков, которые используются более чем один раз, ответ прост:

>>> import itertools 
>>> a = [1,2] 
>>> b = [3,4] 
>>> [i for i in itertools.product(a, b, b)] 
[(1, 3, 3), (1, 3, 4), (1, 4, 3), (1, 4, 4), (2, 3, 3), (2, 3, 4), (2, 4, 3), (2, 4, 4)] 

Но в случае repetition is not allowed в тех же списках, он будет немного противно, и вы должны объединить выше ответьте combinations() и chain() (то же, что указано tobias_k). Этот код даст список всех combinations:

>>> from itertools import chain, product, combinations 
>>> lists, counts = [a, b], [1, 2] # to track that a is to be used once, and b twice 
>>> list(list(chain(*p)) for p in product(*(combinations(l, c) for l, c in zip(lists, counts)))) 
[[1, 3, 4], [2, 3, 4]] 

Однако, в случае, если вам нужны перестановки вместо комбинаций, вы должны обновить код выше с permutations():

>>> from itertools import chain, product, permutations 
>>> list(list(chain(*p)) for p in product(*(permutations(l, c) for l, c in zip(lists, counts)))) 
[[1, 3, 4], [1, 4, 3], [2, 3, 4], [2, 4, 3]] 
+1

Не совсем ясно из вопроса, но я думаю, что тогда последняя строка ожидаемого вывода должна содержать '[13, 14], [11, 12]' вместо '[11, 12], [ 13, 14]. –

+1

@tobias_k При взгляде на его образец, я считаю, что ему нужен декартовой продукт из списков. Обновлен ответ простым примером. И я согласен с вами, входящие параметры OP предоставляются слишком большими и не дают четкого представления о его намерениях. Простой пример был бы полезным –

+0

заказ не имеет значения –