0

PythonでROT13スクリプトを書いています。文字列を単一文字のリストに分割し、for ループを使用して機能し、各文字を調べて、辞書で翻訳する必要があるかどうかを確認します。

問題は、リスト内の文字が常に置き換えられるとは限らないことです。理由はわかりませんが、一部の文字列しか機能しません。

コードは次のとおりです。

import string
def rot13(m):
    Data for ROT13 conversion                                                        
    alphabet = list("abcdefghijklmnopqrstuvwxyz")
    mapping = {}
    for letter in alphabet:
        mapping[letter] = alphabet[(alphabet.index(letter) + 13)%26]
    for letter in alphabet:
        mapping[letter.upper()] = alphabet[(alphabet.index(letter) +13)%26].upper()
    # Create a list of the characters in order                                         
    characters = list(m)
    # Go through each character in the list...                                         
    for character in characters:
        # Check if that character is one that needs to be changed                      
        if character in mapping:
            # Test to chcek if it is finding characters correctly (it is)              
            print "%s to %s" % (character, mapping[character])
            # replace the character with a new one (works inconsistently)              
            characters[characters.index(character)] = mapping[character]
        #Bring it all together                                                         
        result = string.join(characters, "");
    return result

print rot13("ABCDEF") # Returns NOPQRS                                                 
print rot13("ABCDEFGHIJKLMNOPQRSTUVWXYZ") # Returns original string 

大文字のアルファベットの一部を含む最初のテストは、期待どおりに出力されます。ただし、ROT13 関数を使用すると、完全なアルファベットは元の文字列を返すだけです。

問題は 20 行目にあると確信していますcharacters[characters.index(character)] = mapping[character]

この行は、リスト内の文字を、最初に構築された rot13 辞書の対応する文字に置き換えることになっていますが、常にそうするとは限りません。

テストしている文字と、辞書に基づいて変更する必要がある文字を出力する直前の行があり、それは常に機能します。しかし、もしそうなら、なぜこの別の行ではないのでしょうか?

4

4 に答える 4

0

characters.index(character)その文字に等しい最初の要素のインデックスを見つけます。

for character in charactersループの 13 回の繰り返しの後、次のcharactersようlist("NOPQRSTUVWXYZNOPQRSTUVWXYZ")characterなります。もちろん。"N"characters.index(character)0characters[0] = mapping["N"]characters[13] = mapping["N"]mapping["N"] == "A"

試す:

for index, character in enumerate(characters):
    # Check if that character is one that needs to be changed                      
    if character in mapping:
        # Test to chcek if it is finding characters correctly (it is)              
        print "%s to %s" % (character, mapping[character])
        # replace the character with a new one (works inconsistently)              
        characters[index] = mapping[character]
    #Bring it all together                                                         
    result = string.join(characters, "");
于 2013-07-02T03:09:26.543 に答える
0

Index は、リスト内で最初に一致する文字を見つけます。最初の 13 回の繰り返しで、アルファベットが nz に変わり、2 回繰り返されます。次に、2 番目の 13 回の反復で元に戻されます。14 回目の反復では、文字として n が取得され、代わりに a が必要であることが計算され、インデックス ('n') が呼び出されて 0 が取得されます。最初の「n」を「a」に置き換えて次に進みます。

これを書くためのより良い方法はたくさんありますが、まずは enumerate 組み込み関数について読むべきです。毎回検索するのではなく、リストの位置を自分で追跡することで、少なくともこの問題を乗り越えることができます。

于 2013-07-02T03:16:17.800 に答える
0

サイズについては、このバージョンを試してみてください。デバッグが少し簡単になるはずです。

def translate_char(c):
    """Translate a single character using a dictionary"""
    translation_table = {
        'a':'n',
        'b':'o',
        'c':'p',
        'd':'q',
        'e':'r',
        'f':'s',
        'g':'t',
        'h':'u',
        'i':'v',
        'j':'w',
        'k':'x',
        'l':'y',
        'm':'z',
        'n':'a',
        'o':'b',
        'p':'c',
        'q':'d',
        'r':'e',
        's':'f',
        't':'g',
        'u':'h',
        'v':'i',
        'w':'j',
        'x':'k',
        'y':'l',
        'z':'m',
        'A':'N',
        'B':'O',
        'C':'P',
        'D':'Q',
        'E':'R',
        'F':'S',
        'G':'T',
        'H':'U',
        'I':'V',
        'J':'W',
        'K':'X',
        'L':'Y',
        'M':'Z',
        'N':'A',
        'O':'B',
        'P':'C',
        'Q':'D',
        'R':'E',
        'S':'F',
        'T':'G',
        'U':'H',
        'V':'I',
        'W':'J',
        'X':'K',
        'Y':'L',
        'Z':'M'}
    if c in translation_table.keys():
        return translation_table[c]
    else:
        return c    

def rot13(plaintext):
    """Translate a complete string"""
    ciphertext = ""
    for c in plaintext: 
        ciphertext = ciphertext + translate_char(c)
    return ciphertext

if __name__ == "__main__":

    plaintext = "The quick brown fox jumped over the lazy black dog."
    print rot13(plaintext)
于 2013-07-02T03:37:34.783 に答える
0

maketrans フォーム文字列モジュールを使って以下のように実装しました。

from string import maketrans
def rot_it(text):
      intab = "abcdefghijklmnopqrstuvwxyz"
      in_rot = intab + intab.upper()
      outtab = "nopqrstuvwxyzabcdefghijklm"
      out_rot = outtab + outtab.upper()
      trans = maketrans(in_rot, out_rot)
      rot13 = text.translate(trans)
      return rot13
于 2013-07-02T04:00:15.060 に答える