2016-10-02 4 views
1

Ich benutze Python 2.7. Gibt es bei einer Liste von Sets eine schnelle und effiziente Möglichkeit, die Kombinationen zu generieren? Eingabegeräte haben immer ein Element in jedem Satz und Ausgangssätze haben alle Länge von 2

Von:Finden Sie Kombinationen aus einer Liste von Sets

[set(['item1']), set(['item2']), set(['item3'])] 

An:

[set(['item1','item2']), set(['item2','item3']), set(['item3','item1'])] 
+1

Blick auf die 'itertools' Modul –

+3

Dieses viel klarer sein muss. Können Sie ein Beispiel geben, bei dem die Eingabesätze nicht alle die Länge 1 haben? Muss die Ausgabe in einer bestimmten Reihenfolge sein? Warum haben die Ausgabesätze alle die Länge 2? –

+0

@AlexHall Entschuldigung. Das war nicht Teil meiner Überlegung. Dachte nie daran = x. Eingabesätze haben jedoch immer einen Eintrag in jedem Satz und Ausgabesätze haben alle die Länge 2. – ysj

Antwort

3

Da die Elemente in der Liste der Sätze Alle 1-Element-Sets, die Kombinationen, nach denen Sie suchen, sind nur die 2-Element-Teilmengen der Vereinigung dieser Sets.

>>> import itertools 

>>> sets = [set(['item1']), set(['item2']), set(['item3'])] 
>>> elements = set() 
>>> for s in sets: elements.update(s) 

so

>>> elements 
{'item1', 'item2', 'item3'} 

Und dann, gerade diese: Sie können sie wie folgt erhalten

>>> pairs = [set(combo) for combo in itertools.combinations(elements,2)] 
>>> pairs 
[{'item1', 'item2'}, {'item1', 'item3'}, {'item2', 'item3'}] 
+0

Vielen Dank! Genau das will ich haben. Danke für die Erklärung. – ysj

1

Wie John wies darauf hin, itertools könnte hilfreich sein. Hier ist ein kurzes Beispiel:

import itertools as it 
sets = [set(range(0, 3)), set(range(2, 5)), set(range(4, 7))] 
comb = list(it.combinations(sets, r=2)) 
comb 

Ausgang: [({0, 1, 2}, {2, 3, 4}), ({0, 1, 2}, {4, 5, 6}), ({2, 3, 4}, {4, 5, 6})]

Dann eine Kreuzung schaffen in jeder Iteration:

comb_sets = [a.intersection(b) for a, b in comb] 
comb_sets 

Ausgang: [{2}, set(), {4}]

Verwandte Themen