2016-05-12 18 views
0

Ich habe das Programm unten, die an eine andere Funktion übergeben wird, die einfach die ursprünglichen und verschlüsselten Nachrichten druckt. Ich möchte wissen, wie ich dieses Programm vereinfachen, insbesondere die „match = zip“ und „change = (reduzieren (Lambda“ Linien. Wenn möglich, dies zu tun, ohne Lambda zu verwenden, wie kann ich das?Vereinfachen Vigenere Chiffre-Programm in Python

from itertools import cycle 

alphabet = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"] 

def vigenereencrypt(message,keyword): 
    output = ""  
    match = zip(message.lower(),cycle(keyword.lower())) 
    for i in match: 
     change = (reduce(lambda x, y: alphabet.index(x) + alphabet.index(y), i)) % 26 
     output = output + alphabet[change] 
    return output.lower() 

Antwort

2

Zwei Dinge:

  1. Sie brauchen nicht eine lokale Variable match, nur Schleife haben zip
  2. Sie können Ihren beiden Indizes x und y in Ihrer for-Schleife Definition aufgeteilt, anstatt reduce verwendet; reduzieren normalerweise für größere verwendet iterables und sin Wenn Sie nur 2 Elemente in i haben, fügt das unnötige Komplexität hinzu.

dh, können Sie Ihre for-Schleife Definition ändern:

for x, y in zip(...): 

und Ihre Definition von change zu:

change = (alphabet.index(x) + alphabet.index(y)) % 26 
+0

Fantastisch. Ich <3 es. – kpie

0

Sie es mit einem Bündel von Indizierung statt zip tun könnte ...

alphabet = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"] 
alphaSort = {k:n for n,k in enumerate(alphabet)} 
alphaDex = {n:k for n,k in enumerate(alphabet)} 

def vigenereencrypt(message,keyword): 
    output = ""  
    #match = zip(message.lower(),cycle(keyword.lower()))  # zip(a,cycle(b)) Creates [(a[n],b[n%len(b)]) for k in range(len(a)) ] 
    op = ""             # So lets start with for k in range(len(a)) 
    for k in range(len(message)): 
     op += alphaDex[(alphaSort[message.lower()[k]]+alphaSort[keyword.lower()[k%len(keyword)]])%len(alphabet)] 
    return(op) 
1

Beginnen mit was R Nar sagte:

def vigenereencrypt(message,keyword): 
    output = "" 
    for x, y in zip(message.lower(), cycle(keyword.lower())): 
     change = (alphabet.index(x) + alphabet.index(y)) % 26 
     output = output + alphabet[change] 
    return output.lower() 

Wir unter Verwendung einer Liste effizienter sein kann und es dann kam, anstelle der Zugabe in einen String, und auch zu bemerken, dass der Ausgang bereits Klein ist:

def vigenereencrypt(message,keyword): 
    output = [] 
    for x, y in zip(message.lower(), cycle(keyword.lower())): 
     change = (alphabet.index(x) + alphabet.index(y)) % 26 
     output.append(alphabet[change]) 
    return "".join(output) 

dann können wir den Körper der Schleife auf eine Zeile reduzieren ..

def vigenereencrypt(message,keyword): 
    output = [] 
    for x, y in zip(message.lower(), cycle(keyword.lower())): 
     output.append(alphabet[(alphabet.index(x) + alphabet.index(y)) % 26]) 
    return "".join(output) 

... so können wir es in eine Liste Verständnis drehen:

Ich habe das Gefühl, dass wir etwas mit map(alphabet.index, ...) machen können, aber ich kann mir keinen besseren Weg vorstellen, als das Listenverständnis.