8

我正在编写代码,以便您可以将文本沿字母表移动两个位置:“ab cd”应该变成“cd ef”。我正在使用 Python 2,这就是我目前所得到的:

def shifttext(shift):
    input=raw_input('Input text here: ')
    data = list(input)
    for i in data:
        data[i] = chr((ord(i) + shift) % 26)
        output = ''.join(data)
    return output
shifttext(3)

我收到以下错误:

File "level1.py", line 9, in <module>
    shifttext(3)
File "level1.py", line 5, in shifttext
    data[i] = chr((ord(i) + shift) % 26)
TypError: list indices must be integers, not str

所以我必须以某种方式将字母更改为数字?但我想我已经这样做了?

4

5 回答 5

10

您正在遍历字符列表,i因此是一个字符。然后,您尝试将其存储回data使用i字符作为索引。那是行不通的。

用于enumerate()获取索引值:

def shifttext(shift):
    input=raw_input('Input text here: ')
    data = list(input)
    for i, char in enumerate(data):
        data[i] = chr((ord(char) + shift) % 26)
    output = ''.join(data)
    return output

您可以使用生成器表达式来简化它:

def shifttext(shift):
    input=raw_input('Input text here: ')
    return ''.join(chr((ord(char) + shift) % 26) for char in input)

但是现在你会注意到你的% 26行不通;ASCII 码点在 26 之后开始:

>>> ord('a')
97

您需要使用该ord('a')值才能使用模数;减法将您的值置于 0-25 范围内,然后再次添加:

    a = ord('a')
    return ''.join(chr((ord(char) - a + shift) % 26) + a) for char in input)

但这仅适用于小写字母;这可能很好,但是您可以通过小写输入来强制执行此操作:

    a = ord('a')
    return ''.join(chr((ord(char) - a + shift) % 26 + a) for char in input.lower())

如果我们然后从函数中请求输入以使其专注于做好一项工作,则变为:

def shifttext(text, shift):
    a = ord('a')
    return ''.join(chr((ord(char) - a + shift) % 26 + a) for char in text.lower())

print shifttext(raw_input('Input text here: '), 3)

并在我看到的交互式提示中使用它:

>>> print shifttext(raw_input('Input text here: '), 3)
Input text here: Cesarsalad!
fhvduvdodgr

当然,现在标点符号被带走了。上次修订,现在只转换字母:

def shifttext(text, shift):
    a = ord('a')
    return ''.join(
        chr((ord(char) - a + shift) % 26 + a) if 'a' <= char <= 'z' else char
        for char in text.lower())

我们得到:

>>> print shifttext(raw_input('Input text here: '), 3)
Input text here: Ceasarsalad!
fhdvduvdodg!
于 2013-01-20T12:37:00.970 回答
9

看起来你正在做 cesar-cipher 加密,所以你可以尝试这样的事情:

strs = 'abcdefghijklmnopqrstuvwxyz'      #use a string like this, instead of ord() 
def shifttext(shift):
    inp = raw_input('Input text here: ')
    data = []
    for i in inp:                     #iterate over the text not some list
        if i.strip() and i in strs:                 # if the char is not a space ""  
            data.append(strs[(strs.index(i) + shift) % 26])    
        else:
            data.append(i)           #if space the simply append it to data
    output = ''.join(data)
    return output

输出:

In [2]: shifttext(3)
Input text here: how are you?
Out[2]: 'krz duh brx?'

In [3]: shifttext(3)
Input text here: Fine.
Out[3]: 'Flqh.'

strs[(strs.index(i) + shift) % 26]:上面的行意味着找到字符的索引,i然后strs将移位值添加到它。现在,在最终值(索引+移位)上应用 %26 来获取移位索引。当传递给时,这个移位的索引会strs[new_index] 产生所需的移位字符。

于 2013-01-20T12:45:53.453 回答
2

Martijn的回答很棒。这是实现相同目的的另一种方法:

import string

def shifttext(text, shift):
    shift %= 26 # optional, allows for |shift| > 26 
    alphabet = string.lowercase # 'abcdefghijklmnopqrstuvwxyz' (note: for Python 3, use string.ascii_lowercase instead)
    shifted_alphabet = alphabet[shift:] + alphabet[:shift]
    return string.translate(text, string.maketrans(alphabet, shifted_alphabet))

print shifttext(raw_input('Input text here: '), 3)
于 2015-05-30T08:50:32.960 回答
1

写一个直接的函数更容易shifttext(text, shift)。如果需要提示,请使用 Python 的交互模式python -i shift.py

> shifttext('hello', 2)
'jgnnq'
于 2013-01-20T12:34:17.000 回答
1

尝试使用基本 python。可能对某人有用。

# Caesar cipher
import sys

text = input("Enter your message: ")

cipher = ''
try:
  number = int(input("Enter Number to shift the value : "))
except ValueError:
  print("Entered number should be integer. please re0enter the value")
  try:
    number = int(input("Enter Number to shift the value : "))
  except:
    print("Error occurred. please try again.")
    sys.exit(2)
  
for char in text:
    if not char.isalpha():
      flag = char
    elif char.isupper():
      code = ord(char) + number
      if 64 < code <= 90:
        flag = chr(code)
      elif code > 90:
        flag = chr((code - 90) + 64)
        
    elif char.islower():
      code = ord(char) + number
      if 96 < code <= 122:
        flag = chr(code)
      elif code > 122:
        flag = chr((code - 122) + 96)
    
    else:
      print("not supported value by ASCII")
    
    cipher += flag

print(cipher)
于 2020-10-04T22:23:56.110 回答