2015-10-14 13 views
5

Vì vậy, tôi có một danh sách liệt kê các chuỗiPython tất cả các kết hợp của một danh sách liệt kê

[['a','b'],['c','d'],['e','f']] 

và tôi muốn để có được tất cả các kết hợp có thể, như vậy mà kết quả là

[['a','b'],['c','d'],['e','f'], 
['a','b','c','d'],['a','b','e','f'],['c','d','e','f'], 
['a','b','c','d','e','f']] 

Cho đến nay Tôi đã đưa ra đoạn mã này

input = [['a','b'],['c','d'],['e','f']] 
combs = [] 
for i in xrange(1, len(input)+1): 
    els = [x for x in itertools.combinations(input, i)] 
    combs.extend(els) 
print combs 

phần lớn theo sau câu trả lời trong this post.

Nhưng mà kết quả trong

[(['a','b'],),(['c','d'],),(['e','f'],), 
(['a','b'],['c','d']),(['a','b'],['e','f']),(['c','d'],['e','f']), 
(['a','b'],['c', 'd'],['e', 'f'])] 

và tôi hiện đang bối rối, cố gắng tìm một cách pythonic thanh lịch để giải nén những tuples.

Trả lời

6

Bạn có thể sử dụng itertools.chain.from_iterable để làm phẳng danh sách danh sách thành danh sách. Ví dụ -

import itertools 
input = [['a','b'],['c','d'],['e','f']] 
combs = [] 
for i in xrange(1, len(input)+1): 
    els = [list(itertools.chain.from_iterable(x)) for x in itertools.combinations(input, i)] 
    combs.extend(els) 

Demo -

>>> import itertools 
>>> input = [['a','b'],['c','d'],['e','f']] 
>>> combs = [] 
>>> for i in range(1, len(input)+1): 
...  els = [list(itertools.chain.from_iterable(x)) for x in itertools.combinations(input, i)] 
...  combs.extend(els) 
... 
>>> import pprint 
>>> pprint.pprint(combs) 
[['a', 'b'], 
['c', 'd'], 
['e', 'f'], 
['a', 'b', 'c', 'd'], 
['a', 'b', 'e', 'f'], 
['c', 'd', 'e', 'f'], 
['a', 'b', 'c', 'd', 'e', 'f']] 
+1

Tốt. Tôi thường ngạc nhiên trước sự mạnh mẽ của 'itertools'. –

+0

Hoàn hảo. Chính xác những gì tôi đang tìm kiếm. Cảm ơn! –

0

Một ý tưởng cho một mục tiêu như vậy là để lập bản đồ số nguyên từ [0..2**n-1] trong đó n là số các danh sách con cho tất cả các yếu tố mục tiêu của bạn theo một rất đơn giản quy tắc: Lấy phần tử của chỉ mục k nếu (2**k)&i!=0 nơi tôi chạy trên [0..2**n-1]. Nói cách khác, i phải được đọc bitwise và đối với mỗi bit, phần tử tương ứng từ l được giữ lại. Từ quan điểm toán học, nó là một trong những cách sạch nhất để đạt được những gì bạn muốn làm vì nó theo định nghĩa rất chặt chẽ về các phần của bộ (nơi bạn có chính xác 2**n các bộ phận cho một bộ có phần tử n).

Không cố gắng nhưng một cái gì đó như thế nên làm việc:

l = [['a','b'],['c','d'],['e','f']]              
n = len(l) 
output = [] 
for i in range(2**n): 
    s = [] 
    for k in range(n): 
     if (2**k)&i: s = s + l[k] 
    output.append(s) 

Nếu bạn không muốn danh sách rỗng, chỉ cần thay thế dòng tương ứng với:

for i in range(1,2**n): 
0

Nếu bạn muốn tất cả kết hợp, bạn có thể xem xét cách đơn giản này:

import itertools 

a = [['a','b'],['c','d'],['e','f']] 
a = a + [i + j for i in a for j in a if i != j] + [list(itertools.chain.from_iterable(a))] 
+0

Nếu danh sách ban đầu chứa 4 danh sách, điều này sẽ không chứa kết hợp kết quả của độ dài 3, mặc dù. –

+0

@Matt M. Vâng, bạn nói đúng, tôi không xem danh sách chứa 4 danh sách, chỉ hiển thị một trường hợp đơn giản. trong trường hợp có hơn 3 danh sách, phương pháp của Anand S Kumar sẽ là phương pháp bạn cần. Cảm ơn bạn đã cho tôi biết. –

0

Với danh sách hiểu:

combs=[sum(x,[]) for i in range(len(l)) for x in itertools.combinations(l,i+1)] 
Các vấn đề liên quan