2017-10-02 2 views
1

Ich kenne viele Beiträge mit ähnlichen Fragen und habe viele davon durchgemacht. Ich kann jedoch nicht tun, was ich brauche.Aufteilen einer Liste in alle Kombinationen

Ich habe Liste L = [0,1,2,3,4,5], die ich in ein Paar Tupel aufteilen möchte. Beispiel:

[(0,1,2),(3,4,5)] 
[(0,1,3),(2,4,5)] 
[(0,1,4),(2,4,5)] 
... 

Jedes Tupel muss die Hälfte der Elemente aus der ursprünglichen Liste enthalten (in diesem Beispiel 3 von 6). Eine Lösung muss jede Kombination von Tupeln mit 3 Elementen erzeugen.

Ich kann alle möglichen Tupel innerhalb der Liste mit

list(itertools.combinations(L, 3)) 

[(0, 1, 2), (0, 1, 3), (0, 1, 4), (0, 1, 5), (0, 2, 3), (0, 2, 4), ...]

Does itertools bietet jede workround für diese auch leicht finden?

+0

Es Art auf die davon abhängt, ob alle Listenelemente sind einzigartig und wie Sie behandeln wollen Duplikate. Sie könnten versuchen, 'set' zu verwenden oder alle möglichen Permutationen der ursprünglichen Liste zu erstellen und jede Permutation in zwei Hälften zu teilen. – mkrieger1

+0

Haben Sie einen doppelten Wert in dieser Liste? – Lafexlos

+0

Im Moment gibt es keine Duplikate, aber eine allgemeine Lösung wäre toll – ErroriSalvo

Antwort

4

Es kann mehr performant Lösungen sein, die eine komplette zusätzliche Iteration der Liste für die andere Hälfte zu vermeiden, aber das sollte nicht vernachlässigt werden:

l = [[x, tuple(y for y in L if y not in x)] for x in combinations(L, 3)] 
[[(0, 1, 2), (3, 4, 5)], 
[(0, 1, 3), (2, 4, 5)], 
[(0, 1, 4), (2, 3, 5)], 
[(0, 1, 5), (2, 3, 4)], 
[(0, 2, 3), (1, 4, 5)], 
[(0, 2, 4), (1, 3, 5)], 
[(0, 2, 5), (1, 3, 4)], 
[(0, 3, 4), (1, 2, 5)], 
[(0, 3, 5), (1, 2, 4)], 
[(0, 4, 5), (1, 2, 3)], 
[(1, 2, 3), (0, 4, 5)], 
[(1, 2, 4), (0, 3, 5)], 
[(1, 2, 5), (0, 3, 4)], 
[(1, 3, 4), (0, 2, 5)], 
[(1, 3, 5), (0, 2, 4)], 
[(1, 4, 5), (0, 2, 3)], 
[(2, 3, 4), (0, 1, 5)], 
[(2, 3, 5), (0, 1, 4)], 
[(2, 4, 5), (0, 1, 3)], 
[(3, 4, 5), (0, 1, 2)]] 

Dies hängt von der Abwesenheit von Duplikaten in der ursprünglichen Liste. Andernfalls müssten Sie stattdessen mit den Indizes arbeiten. Die folgende Modifikation verwendet den gleichen Ansatz, sondern verwendet die Liste Indizes für die Kombinationen und kann somit Duplikate in der ursprünglichen Liste behandeln:

indexes = ((x, (y for y in L if y not in x)) for x in combinations(range(len(L)), 3)) 
l = [[tuple(L[a] for a in A), tuple(L[b] for b in B)] for A, B in indexes] 
+0

Sie könnten alles innerhalb 'tuple' durch' set (L) ersetzen - setzen (x) ' –

+1

Das würde jedoch die Reihenfolge gefährden, und ich bin ziemlich sicher, dass es einen erheblichen Overhead für die gesetzten Konvertierungen gibt. – schwobaseggl

Verwandte Themen