2015-08-17 9 views
5

Ich versuche, eine Möglichkeit zu finden, alle möglichen eindeutigen Zeichenfolgen aus einem Alphabet von 20 Zeichen zu generieren, wobei die Reihenfolge innerhalb der Zeichenfolge keine Rolle spielt und die Länge der Zeichenfolge kann variieren. So wären zum Beispiel für eine Zeichenkette der Länge 3 die möglichen Zeichenketten AAA, AAB, AAC usw., würden aber BAA oder CAA nicht einschließen. Ich habe einen Weg gefunden mit itertools.product(), aber es ist sehr rechenintensiv. Der einfachste Weg dazu besteht in der Verwendung von verschachtelten for-Schleifen. Zum Beispiel alle Strings der Länge erzeugen vier:Variable Anzahl von vorhersagbaren Schleifen in Python

alphabet = ["A","C","D","E","F","G","H","I","K","L", 
      "M","N","P","Q","R","S","T","V","W","Y"] 
combos = [] 
for a in range(len(alphabet)): 
    for b in range(a,len(alphabet)): 
     for c in range(b,len(alphabet)): 
      for d in range(c,len(alphabet)): 
       combos.append(alphabet[a] + alphabet[b] + alphabet[c] + alphabet[d]) 

Nun, dies leicht für jede Zeichenfolge kann getan werden, indem die Anzahl der für Schleifen zu ändern. Gegeben die For-Schleife Sequenz selbst ist ziemlich vorhersehbar, gibt es Weg, diesen Code zu vereinfachen, statt if length == 3 drei For-Schleifen und if length == 4 führen vier Schleifen statt? Der einzige Weg, ich denke, kann es jetzt zu tun ist, ein Bündel von if-elif Aussagen:

if length == 3: 
    for a in range(len(alphabet)): 
     for b in range(a,len(alphabet)): 
      for c in range(b,len(alphabet)): 
       combos.append(alphabet[a] + alphabet[b] + alphabet[c]) 
elif length == 4: 
    for a in range(len(alphabet)): 
     for b in range(a,len(alphabet)): 
      for c in range(b,len(alphabet)): 
       for d in range(c,len(alphabet)): 
        combos.append(alphabet[a] + alphabet[b] + alphabet[c] + alphabet[d]) 

Gibt es einen einfacheren Weg, als nur eine Reihe von möglichen Werten der Länge abdeckt?

+3

Können Sie mehr über Ihre versuchte/fehlgeschlagene Lösung mit 'itertools.product' sagen? Ihr Weg sollte viel rechenintensiver sein. –

+1

@ Two-BitAlchemist: Nein, der OP-Code ist besser, weil er nur die erzeugt, die er benötigt. Mit dem Produkt, in dem Fall mit 4 Buchstaben, würden Sie 151145/160000 der Ergebnisse wegwerfen. – DSM

Antwort

3

IIUC Sie einfach itertools.combinations_with_replacement verwenden können .

>>> list(map(''.join, combinations_with_replacement(["a","b","c"],2))) 
['aa', 'ab', 'ac', 'bb', 'bc', 'cc'] 
>>> list(map(''.join, combinations_with_replacement(["a","b","c"],3))) 
['aaa', 'aab', 'aac', 'abb', 'abc', 'acc', 'bbb', 'bbc', 'bcc', 'ccc'] 
>>> list(map(''.join, combinations_with_replacement(alphabet,4))) == orig(alphabet) 
True 

(wobei orig ist einfach Ihr ursprünglicher Code in eine Funktion verpackt).

+0

war nur auf die gleiche Antwort, würde Produkt geben völlig unterschiedliche Ausgabe –

+0

@PadraicCunningham: dann bin ich mir nicht sicher, verstehe ich Ihre Kommentar-Frage zum OP - der OP-Code ist effizienter als Produkt, weil er nur die er erzeugt Bedürfnisse, anstatt auf alle von ihnen zu schauen und diejenigen herauszufiltern, die er nicht will. – DSM

+0

Ich sah nicht auf den OP-Code zunächst, ich vermutete, sie wollten das Produkt unter Berücksichtigung, dass sie mit Produkt –