Python中的文本移位函数

Python中的文本移位函数,python,python-2.7,Python,Python 2.7,我在写代码,这样你就可以把文本沿着字母表移动两个位置:“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

我在写代码,这样你就可以把文本沿着字母表移动两个位置:“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
文件“level1.py”,第9行,在
移位文本(3)
shifttext中第5行的文件“level1.py”
数据[i]=chr((命令(i)+移位)%26)
类型错误:列表索引必须是整数,而不是str

所以我得把字母改成数字?但是我认为我已经做到了?

编写一个简单的函数
shifttext(text,shift)
。如果需要提示,请使用Python的交互模式
Python-i shift.py

> shifttext('hello', 2)
'jgnnq'

您在字符列表上循环,因此
i
是一个字符。然后尝试使用
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())

看起来您正在执行cesar密码加密,因此您可以尝试以下操作:

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]
:上面的行表示在
strs
中查找字符
i
的索引,然后将移位值添加到其中。现在,在最终值(index+shift)上应用%26以获取移位索引。当传递到strs[new_index]
时,这个移位的索引将产生所需的移位字符。

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)
尝试使用基本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)
#凯撒密码
导入系统
text=输入(“输入您的消息:”)
密码=“”
尝试:
number=int(输入(“输入数字以移动值:”))
除值错误外:
打印(“输入的数字应为整数。请重新输入值”)
尝试:
number=int(输入(“输入数字以移动值:”))
除:
打印(“出现错误。请重试”)
系统出口(2)
对于文本中的字符:
如果不是char.isalpha():
flag=char
elif char.isupper():
代码=ord(字符)+数字
如果64<代码90:
flag=chr((代码-90)+64)
elif char.islower():
代码=ord(字符)+数字
如果96<代码122:
flag=chr((代码-122)+96)
其他:
打印(“ASCII不支持值”)
密码+=标志
打印(密码)

我想你忘了调用函数了,试试:
shifttext(3)
。你有没有试过用
print
替换
return
?如果我打印了,我就什么也得不到,如果我真的调用它(很好!)我会出错,我会把它添加到问题中,谢谢!而且,
ord('a')
是97,因此
%26
将产生不需要的结果。您也不需要在for循环中重新分配
输出。回溯是因为
data[i]
-也许你想在枚举(data):data[i]…
el
是实际的字母,
i
是索引。我猜使用maketrans会更容易,因为标点符号仍然存在。
ord('a')
是97,因此,
%26
仍将生成随机字符。Kay,错误已经消失,但我没有得到任何返回。如果我改为打印,我会得到3行空行。是的!现在我开始工作了,谢谢你一步一步的积累!:-)<代码>输出=“”。联接(数据)不应在for中loop@AmpiSevere:您必须检测要转换的字符;测试范围
'a'@AmpiSevere您的输入是什么?一段移位(无法理解)的文本,由单词、空格组成,并以句号和一个撇号结尾。@AmpiSevere我已经修改了代码来处理这些字符(即,;”)还有。好的,没有错误,但现在我没有得到返回,在函数定义之后,我实际上调用了它。我几乎在所有事情上都遇到了这个问题,我不知道它从何而来。@AmpiSevere请尝试这样调用函数:
print shifttext(3)
# 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)