2016-07-05 14 views
2

Okay, ich habe an einem Code gearbeitet, der alle möglichen Kombinationen der eingegebenen verschlüsselten Buchstaben enthält. Hier ist es:Duplikate landen trotz "if statement" in der Liste

import random, math 

words = [] 
original = raw_input("What do you need scrambled? ") 

def word_scramble(scrambled): 

    original_length = len(scrambled) 
    loops = math.factorial(original_length) 

    while loops > 0: 
     new_word = [] 

     used_numbers = [] 

     while len(new_word) < original_length: 

      number = random.randint(0, original_length - 1) 

      while number in used_numbers: 
       number = random.randint(0, original_length - 1) 

      while number not in used_numbers: 
       used_numbers.append(number) 
       new_word.append(scrambled[number]) 

     if new_word not in words: 
      words.append(("".join(str(x) for x in new_word))) 
      loops -= 1 

word_scramble(original) 

print ("\n".join(str(x) for x in words)) 

Das Problem ist, es gibt immer noch Duplikate, obwohl es nicht soll. Zum Beispiel kann ich "imlk" eingeben und bekomme manchmal zweimal "Milch", während ich immer noch nur 24 Permutationen habe, was bedeutet, dass einige Permutationen ausgeschlossen werden. Das:

if new_word not in words: 
    words.append(("".join(str(x) for x in new_word))) 
    loops -= 1 

soll verhindern, dass Duplikate in der Liste sind. Ich bin mir also nicht wirklich sicher, was das Problem ist. Und tut mir leid, dass der Haupttitel der Frage so vage/seltsam war. Ich war mir nicht sicher, wie ich es besser ausdrücken sollte.

Antwort

2

Vom doc:

itertools.permutations (iterable [r])

Return aufeinanderfolgenden R Länge Permutationen von Elementen in der iterable.

Wenn r nicht angegeben ist oder None ist, dann ist r standardmäßig auf die Länge von iterierbar und alle möglichen Permutationen mit voller Länge werden generiert.

import itertools 
word=raw_input() 
scramble_all = [''.join(p) for p in itertools.permutations(word)] 
print scramble_all 

Ausgang:

[ 'Milch', 'mikl', 'Mlik', 'mlki', 'mkil', 'mkli', 'imlk', ‚imkl ', ' ilmk ',' ilkm ',' ikml ',' iklm ',' lmik ',' lmki ',' limk ',' likm ', ' lkmi ',' lkim ',' kmil ',' kmli ',' kiml ',' kilm ',' klmi ',' klim ']

3
if new_word not in words: 
    words.append(("".join(str(x) for x in new_word))) 
    loops -= 1 

new_word ist eine Liste von Buchstaben, aber words enthält Strings keine Listen von Buchstaben. Sie sind in verschiedenen Formaten, so dass der Check immer erfolgreich sein wird.

Zum Beispiel könnten Sie den Scheck erhalten:

if ['m', 'i', 'l', 'k'] not in ['imlk', 'milk', 'klim'] 

statt

if 'milk' not in ['imlk', 'milk', 'klim'] 

By the way, Ihr Algorithmus wird sehr dringend benötigt, die mehr Buchstaben maßstabs es unkenntlich zu machen. Es beruht darauf, zufällig auf unbenutzte Wörter zu stolpern, was zuerst schnell ist, aber langsamer, je mehr Wörter verwendet werden.

Sie sind besser dran, wenn Sie einen Weg finden, die Permutationen in einer vorhersagbaren Reihenfolge ohne Raten zu zählen.

6

Wie wäre es mit itertools.permutations?

import itertools 
original = raw_input("What do you need scrambled? ") 
result = [''.join(s) for s in itertools.permutations(original)] 
+0

Die Länge ist standardmäßig die Länge des Iterablen. So ist 'len (original)' nicht erforderlich. – SilentMonk

+1

@SilentMonk: Guter Fang. Vielen Dank. –

+1

Standardbibliothek FTW. – u8y7541

0

Ignorieren Sie Ihre ursprüngliche Frage kann eine bessere Lösung für die Generierung aller Kombinationen bieten.Nur zur Erinnerung, es gibt einen Unterschied zwischen allen möglichen Kombinationen und Permutationen.

Eine Kombination ist, wo die Reihenfolge einer Teilmenge von Elementen aus einem Satz keine Rolle spielt. Zum Beispiel sind "bac" und "abc" gleichwertige Kombinationen. Das Gegenteil ist der Fall für eine Permutation, bei der Ordnung eine Rolle spielt, "abc" und "bac" sind nicht gleich Permutationen. Kombinationen sind alle möglichen Teilmengen einer Menge, während Permutationen alle möglichen Anordnungen einer Menge sind.

Vor diesem Hintergrund ist hier ein Algorithmus, um alle möglichen Kombinationen (Teilmengen) eines Satzes zu generieren.

def all_subsets(L): 
    if L == []: 
     return [] 
    result = [] 
    for i in range(len (L)): 
     result += [ [ L[ i ] ] ] 
     result += [ e + [ L[ i ] ] for e in all_subsets(L[ i+1 : ]) ] 
    return result