首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法理解为什么我的字母没有在Python中的凯撒代码中旋转。

无法理解为什么我的字母没有在Python中的凯撒代码中旋转。
EN

Stack Overflow用户
提问于 2017-10-27 10:02:01
回答 2查看 46关注 0票数 0

我已经研究这个问题大约一个星期了,我不知道为什么我的信件不旋转。我不是在找人帮我做代码,而是帮我找出我的问题所在。基本上,我在找一只橡皮鸭来帮助解决这个问题。我见过它旋转最后一个字母,但没有其余的字母。这就是我现在的处境。

代码语言:javascript
复制
from string import ascii_uppercase, ascii_lowercase

def caeser_encrypt(string, step):
    new_string = list(string)

    for i in range(len(new_string)):
        new_ascii = ord(new_string[i]) + step

    if string[i] in ascii_uppercase:
        if new_ascii > 90:
            new_ascii = new_ascii - 90 + 64
        elif new_ascii < 65:
            new_ascii = 91 - 65 - new_ascii

    if string[i] in ascii_lowercase:
        if new_ascii > 122:
            new_ascii = new_ascii - 122 + 96
        elif new_ascii < 97:
            new_ascii = 123 - 97 - new_ascii
        new_string[i] = chr(new_ascii)

    return ''.join(new_string)

def main ():
    string = input('Enter word(s)')
    step = input("How many rotations do you want?")
    step = int(step)

    print(caeser_encrypt(string, step))

if __name__ == "__main__":
    main()
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-10-27 10:09:05

只有最后一个字母是旋转的,因为这个缩进:

对于i在范围(len(New_string)):new_ascii = ord(new_stringi) +步骤,如果ascii_uppercase中的new_ascii > 90: new_ascii = new_ascii - 90 + 64 elif new_ascii < 65: new_ascii =91-65-new_ascii

你的意思是:

代码语言:javascript
复制
for i in range(len(new_string)):
    new_ascii = ord(new_string[i]) + step

    if string[i] in ascii_uppercase:
        if new_ascii > 90:
            new_ascii = new_ascii - 90 + 64
        elif new_ascii < 65:
            new_ascii = 91 - 65 - new_ascii

也就是说,if语句应该缩进for语句下。如果if语句不是这样缩进的,那么它们不是在循环中执行的,而是在for循环之后只执行一次。那时,i被设置为最后一个字母的索引,这就是为什么只旋转最后一个字母的原因。

代码评审

还有许多其他的改进是可能的。

与其像90,65这样的神奇数字,不如使用ord('z')ord('a')

if string[i] in ascii_uppercaseif string[i] in ascii_lowercase是相互排斥的条件,因此它们应该与elif链接在一起。

if string[i] in ascii_uppercaseascii_uppercase中执行线性搜索(在ascii_uppercase中检查每个值直到找到匹配为止),与之不同的是,使用范围检查( if 'A' <= string[i] <= 'Z' )会更有效。

该实现也替换了非字母字符。如果我想旋转“你好世界”,这会给出一个有趣的结果,因为空间。也许这是可以的,但是,这样的话,单词的边界仍然是难以区分的。所以这不是批评,只是个旁白。

将其结合在一起,再加上其他一些小改进,您可以这样编写:

代码语言:javascript
复制
def caeser_encrypt(string, step):
    new_string = list(string)

    for i, c in enumerate(new_string):
        new_ascii = ord(c) + step

        if 'A' <= c <= 'Z':
            new_ascii = ord('A') + (new_ascii - ord('A')) % 26

        elif 'a' <= c <= 'z':
            new_ascii = ord('a') + (new_ascii - ord('a')) % 26

        new_string[i] = chr(new_ascii)

    return ''.join(new_string)
票数 1
EN

Stack Overflow用户

发布于 2017-10-27 10:08:52

这里有一些缩进问题:

  1. for i in range(len(new_string)):循环中只有一件事发生,那就是设置new_ascii。当该循环结束时,i等于len(new_string) - 1,因此它将设置最后一个字符,而不是任何其他字符。
  2. new_string[i] = chr(new_ascii)行是代码将字母添加到新字符串的地方,但是检查缩进--只有在if string[i] in ascii_lowercase:为真时才会出现缩进,因此只有小写字母才会出现缩进。

这应该是可行的:

代码语言:javascript
复制
def caeser_encrypt(string, step):
    new_string = list(string)

    for i in range(len(new_string)):
        new_ascii = ord(new_string[i]) + step

        if string[i] in ascii_uppercase:
            if new_ascii > 90:
                new_ascii = new_ascii - 90 + 64
            elif new_ascii < 65:
                new_ascii = 91 - 65 - new_ascii

        if string[i] in ascii_lowercase:
            if new_ascii > 122:
                new_ascii = new_ascii - 122 + 96
            elif new_ascii < 97:
                new_ascii = 123 - 97 - new_ascii

        new_string[i] = chr(new_ascii)

    return ''.join(new_string)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46972452

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档