2016-05-12 50 views
0

我有下面的程序,它被傳遞到另一個函數,它只是打印出原始和加密的消息。我想知道我可以簡化這個程序,特別是「匹配=拉鍊」和「變化=(減少(拉姆達」行。如果可能的話要做到這一點,而不使用lambda,哪能?在Python中簡化Vigenere密碼程序

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() 

回答

2

兩個事情:

  1. 你不需要有一個局部變量match,只是環zip
  2. 你可以先分割你的兩個指數在for循環定義xy而不是使用reduce;減少通常用於大可迭代和罪惡如果您只有i中的2件商品,則會增加不必要的複雜性。

也就是說,你可以循環定義更改到:

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

以及你的change定義:

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

太棒了。我<3。 – kpie

0

你可以用一堆索引,而不是拉鍊的做...

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

從什麼開始[R納爾說:

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() 

我們可以通過使用一個列表,然後加入它,而不是添加一個字符串更高效,並且還注意到,輸出已經小寫:

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) 

然後,我們可以將循環體減少到一個行..

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) 

......所以我們可以把它變成一個列表理解:

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

我覺得我們可以用map(alphabet.index, ...)做些事情,但我想不出比列表理解更好的方法。