2016-05-23 22 views
-3
def encrypt_caesar(plaintext): 
    s = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 
    d = dict(map(s,s[3:]+ s[:3])) 
    return ''.join(map(lambda l: d.get(l,l), plaintext.lower())) 

試過這個代碼從斯坦福大學的演講幻燈片複製並運行它,但它給'str' object is not callable錯誤,我究竟做錯了什麼?「海峽」對象不是凱撒加密贖回

+1

你有什麼期望了'圖()'產生?你正試圖在那裏使用's'作爲*函數*。 –

回答

0

我猜幻燈片的作者實際上並沒有測試的代碼。

您產生的代碼試圖利用map()s作爲一個功能:

map(s,s[3:]+ s[:3]) 
# ^This must be a *callable object*, like a function 

如果你想創建一個字典映射ASCII字母一個字母沿着字母表中的3點,使用zip() function代替:

d = dict(zip(s, s[3:] + s[:3])) 

zip()然後對向上在s每個元素與s[3:] + s[:3]的每個元素,並且這些(letter, letter + 3)雙是然後傳遞給dict()形成鍵值對:

>>> s = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 
>>> dict(zip(s, s[3:] + s[:3])) 
{'A': 'D', 'I': 'L', 'L': 'O', 'X': 'A', 'N': 'Q', 'D': 'G', 'S': 'V', 'B': 'E', 'V': 'Y', 'C': 'F', 'K': 'N', 'W': 'Z', 'R': 'U', 'O': 'R', 'T': 'W', 'P': 'S', 'F': 'I', 'J': 'M', 'M': 'P', 'E': 'H', 'Q': 'T', 'H': 'K', 'G': 'J', 'Z': 'C', 'U': 'X', 'Y': 'B'} 

接下來,你的最後一行將徹底失敗做任何加密,因爲你的地圖只處理大寫字母,但你小寫您輸入。要麼產生一個小寫映射,要麼小寫你的輸入。

Lowercasing地圖上看起來是這樣的:

def encrypt_caesar(plaintext): 
    s = "abcdefghijklmnopqrstuvwxyz" 
    d = dict(zip(s, s[3:] + s[:3])) 
    return ''.join(map(lambda l: d.get(l, l), plaintext.lower())) 

,或者你可以只使用string.ascii_lowercase constant

from string import ascii_lowercase 

def encrypt_caesar(plaintext): 
    d = dict(zip(ascii_lowercase, ascii_lowercase[3:] + ascii_lowercase[:3])) 
    return ''.join(map(lambda l: d.get(l,l), plaintext.lower())) 

使用此方法相當緩慢,但是。對於超炫快「加密」,使用str.translate() method;該輸入映射最好用str.maketrans製備:

from string import ascii_lowercase as alc 

def encrypt_caesar(plaintext, shift=3): 
    map = str.maketrans(alc, alc[shift:] + alc[:shift]) 
    return plaintext.lower().translate(map) 

我添加了一個shift參數來定義多少字母表移位應適用。

我會離開搬運小寫和大寫字母作爲練習讀者!

+0

你是非常正確的,先生,看來我甚至不能正確地複製代碼:( – leftunknown

+0

最後一個例子也確實簡潔,非常感謝! – leftunknown