2016-05-02 5 views
1
l = ['A', 'B', 'C', 'D'] 

Ich möchte alle Kombinationen in Reihenfolge bringen. So sollte die Ausgabe aussehen,Was ist der beste Weg, um Kombinationen in Reihenfolge zu produzieren?

['ABCD', 'ABC', 'AB', 'A', 'BCD', 'BC', 'B', 'CD', 'C', 'D'] 

Was ich versucht habe, ist ..

>>> o = set() 
>>> for i, j in enumerate(l): 
    o.add(''.join(l[:i])) 
    o.add(''.join(l[i:])) 


>>> 
>>> o 
set(['', 'ABCD', 'AB', 'D', 'BCD', 'CD', 'ABC', 'A']) 

Aber es fehlt BC. Auch versucht itertools.combinations aber es bietet alle möglichen Kombinationen unabhängig von der Reihenfolge.

+0

Um genau zu sein, vermissen Sie "B", "C" und "BC" – Antonio

+0

@Antonio ?? Ich fügte hinzu. –

+0

Ihre Frage ist wie [diese] (http://stackoverflow.com/q/17434070/2436175), aber mit der Ausgabe sofort bestellt? – Antonio

Antwort

0

Ich möchte darauf hinweisen, dass jede Kombination einen binären Namen zwischen 0 und 2^n-1 abbildet, wobei n die Länge der ursprünglichen Zeichenfolge ist (Beginnen Sie bei 1, wenn Sie die leere Kombination ignorieren möchten. ABCD ist 1111, ABC ist 1110, und so weiter.

diese Werte generieren und machen die Zuordnung.

Ein anderer Weg, um die gleiche Sache zu suchen, alle Kombinationen für ABCD alle Kombinationen für BCD und alle, die Kombination mit A vorangestellt

4

Wenn Sie nur nach aufeinanderfolgenden Untersegmenten der Liste suchen, iterieren Sie einfach die möglichen Kombinationen von Start- und Endpositionen und erzeugen die entsprechenden Slices. Da die end Position von der start abhängt, glaube ich nicht, dass es eine Möglichkeit gibt, dies mit einer der itertools Funktionen zu tun.

def comb_in_order(lst): 
    for start in range(0, len(lst)): 
     for end in range(len(lst), start, -1): 
      yield lst[start:end] 

Beispiel:

>>> [''.join(c) for c in comb_in_order(['A', 'B', 'C', 'D'])] 
['ABCD', 'ABC', 'AB', 'A', 'BCD', 'BC', 'B', 'CD', 'C', 'D'] 

Sie könnte Verwendung itertools.product mit einer zusätzlichen Bedingung, aber diese Weise können Sie viele Kombinationen durchlaufen wird, die ohnehin herausgefiltert werden, und die Reihenfolge der Ergebnisse etwas anders:

>>> [''.join(lst[s:e+1]) for s,e in itertools.product(range(len(lst)), repeat=2) if s <= e] 
['A', 'AB', 'ABC', 'ABCD', 'B', 'BC', 'BCD', 'C', 'CD', 'D'] 
Verwandte Themen