Python 出于某种原因,每当在if语句中检查条件时,列表的值chars就会重置,从而中断程序

Python 出于某种原因,每当在if语句中检查条件时,列表的值chars就会重置,从而中断程序,python,string,list,algorithm,Python,String,List,Algorithm,我正在尝试创建一个函数,该函数接受字符串并运行以下加密算法:字母表中奇数位置I处的每个字符将使用位置I+1处的字符加密,偶数位置I处的每个字符将使用位置I-1处的字符加密。换句话说,“a”用“b”加密,“b”用“a”,c用“d”,d用“c”加密,等等。小写字符应保持小写,大写字符应保持大写。换句话说,“bob”将输出为“apa” 虽然我最终解决了这个问题,但我仍然不知道为什么在我的条件中使用chars[I]而不是stg[I]会破坏程序。从我的观察来看,这个列表似乎是以随机间隔重新设置的。有人能解

我正在尝试创建一个函数,该函数接受字符串并运行以下加密算法:字母表中奇数位置I处的每个字符将使用位置I+1处的字符加密,偶数位置I处的每个字符将使用位置I-1处的字符加密。换句话说,“a”用“b”加密,“b”用“a”,c用“d”,d用“c”加密,等等。小写字符应保持小写,大写字符应保持大写。换句话说,“bob”将输出为“apa”

虽然我最终解决了这个问题,但我仍然不知道为什么在我的条件中使用chars[I]而不是stg[I]会破坏程序。从我的观察来看,这个列表似乎是以随机间隔重新设置的。有人能解释为什么交换变量修复了我的程序吗?谢谢大家!

坏程序:

def easyCryto(stg=''):

    # Alphabet list
    alpha = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
    cap_alpha = [i.upper() for i in alpha]
    
    # Converts the string into a list
    chars = []
    for char in stg:
        chars.append(char)

    # Encyription Algorithm
    for i in range(len(chars)):
        for j in range(len(alpha)):
            
            # Checks if letter are odd
            if (j + 1) % 2 == 1:
                if chars[i] == alpha[j]:
                    try: # Block 1
                        if chars[i] not in cap_alpha:
                            chars[i] = alpha[j + 1]
                        else:
                            chars[i] = cap_alpha[j + 1]
                    except:
                        if chars[i] not in cap_alpha:
                            chars[i] = alpha[0]
                        else:
                            chars[i] = cap_alpha[0]

                elif chars[i] == cap_alpha[j]:
                    chars[i] = cap_alpha[j + 1]

            # Checks if letter are even
            elif (j + 1) % 2 == 0:
                if chars[i] == alpha[j]:
                    try: # Block 1
                        if chars[i] not in cap_alpha:
                            chars[i] = alpha[j - 1]
                        else:
                            chars[i] = cap_alpha[j - 1]

                    except:
                        if chars[i] not in cap_alpha:
                            chars[i] = alpha[-1]
                        else:
                            chars[i] = cap_alpha[-1]

                elif chars[i] == cap_alpha[j]:
                    chars[i] = cap_alpha[j - 1]

    return ''.join(chars)

print(easyCryto('Willy'))
固定程序:

def easyCryto(stg=''):

    # Alphabet list
    alpha = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
    cap_alpha = [i.upper() for i in alpha]
    
    # Converts the string into a list
    chars = []
    for char in stg:
        chars.append(char)

    # Encyription Algorithm
    for i in range(len(chars)):
        for j in range(len(alpha)):

            # Checks if letter are odd
            if (j + 1) % 2 == 1:
                if stg[i] == alpha[j]:
                    try: # Block 1
                        if stg[i] not in cap_alpha:
                            chars[i] = alpha[j + 1]
                        else:
                            chars[i] = cap_alpha[j + 1]
                    except:
                        if stg[i] not in cap_alpha:
                            chars[i] = alpha[0]
                        else:
                            chars[i] = cap_alpha[0]

                elif stg[i] == cap_alpha[j]:
                    chars[i] = cap_alpha[j + 1]

            # Checks if letter are even
            elif (j + 1) % 2 == 0:
                if stg[i] == alpha[j]:
                    try: # Block 1
                        if stg[i] not in cap_alpha:
                            chars[i] = alpha[j - 1]
                        else:
                            chars[i] = cap_alpha[j - 1]

                    except:
                        if stg[i] not in cap_alpha:
                            chars[i] = alpha[-1]
                        else:
                            chars[i] = cap_alpha[-1]

                elif stg[i] == cap_alpha[j]:
                    chars[i] = cap_alpha[j - 1]

    return ''.join(chars)

print(easyCryto('bob'))

问题是,在替换之后,您永远不会中断循环,因此替换循环会继续进行。当替换“向后”时(例如,将b替换为a),这不是一个问题,因为您正在向前迭代
alpha
,因此它不会再次匹配。但是,当您将
a
替换为
b
时,在循环的下一次迭代中,它将立即找到新的替换匹配项,并将
b
(原来是
a
)交换回
a

只需打印替换循环的状态即可轻松查看:

c=b a=a
c=b a=b
c=a a=c
c=a a=d
c=a a=e
c=a a=f
c=a a=g
c=a a=h
c=a a=i
c=a a=j
c=a a=k
c=a a=l
c=a a=m
c=a a=n
c=a a=o
c=a a=p
c=a a=q
c=a a=r
c=a a=s
c=a a=t
c=a a=u
c=a a=v
c=a a=w
c=a a=x
c=a a=y
c=a a=z
c=o a=a
c=o a=b
c=o a=c
c=o a=d
c=o a=e
c=o a=f
c=o a=g
c=o a=h
c=o a=i
c=o a=j
c=o a=k
c=o a=l
c=o a=m
c=o a=n
c=o a=o
c=p a=p
c=o a=q
c=o a=r
c=o a=s
c=o a=t
c=o a=u
c=o a=v
c=o a=w
c=o a=x
c=o a=y
c=o a=z
c=b a=a
c=b a=b
c=a a=c
c=a a=d
c=a a=e
c=a a=f
c=a a=g
c=a a=h
c=a a=i
c=a a=j
c=a a=k
c=a a=l
c=a a=m
c=a a=n
c=a a=o
c=a a=p
c=a a=q
c=a a=r
c=a a=s
c=a a=t
c=a a=u
c=a a=v
c=a a=w
c=a a=x
c=a a=y
c=a a=z
c=chars[i]
a=alpha[j]
。在
c=b
上,您可以看到更换很快完成,然后我们无缘无故地继续进行,但在
c=o
上,您可以看到它到达
a=o
,翻转到
c=p
,但此时
a=p
,因此我们返回到
c=o

使用
stg
检查这不是一个因素,因为原始数据没有翻转。另一种方法是在找到与
chars[i]
匹配的
alpha[j]
后,
break

但脚本似乎过于复杂:

  • 您在检查
    cap_alpha
    之后,正在检查
    cap_alpha
    ,因为这些集合是不重叠的,我不知道这怎么会有用
  • 尝试/例外似乎没有用?我本可以看到一个模问题,但在你的方案中,
    z
    被替换为
    y
    ,所以没有什么有趣的事情发生
更重要的是,您没有使用Python的功能,例如,
string
已经提供了字母表,
str.translate
可以使用转换表,
list.index
将返回列表中某项的索引(当它找不到任何东西时会引发异常,
str.find
很方便,因为它只返回
None
chr
ord
将从和转换为码点编号,您可以使用位操纵来翻转编号

你也许可以通过玩一些小游戏来实现这一点(甚至可能会很有趣),但作为第一个近似方法,我只需要建立一个翻译表并使用它。这不是最简单的掌握方法,但一旦你尝试了它,它就非常方便了:

#str.maketrans可以采用各种格式来构建翻译
#这里我们将使用最简单的字典映射
#unicode序数(字母代码)到其他unicode序数
#映射是我们想要定义的转换
tr={}
#迭代“奇数”字母的代码(a、c、e、g等)并创建
#要向前(a->b)和向后(b->a)映射的条目
对于范围内的字母(ord('a')、ord('z')、2):
tr[字母]=字母+1
tr[字母+1]=字母
#重复大写字母
对于范围内的字母(ord('A')、ord('Z')、2):
tr[字母]=字母+1
tr[字母+1]=字母
表=str.maketrans(tr)
def easyCryto(stg=''):
返回标准转换(表)
打印(easyCryto('Willy'))

通过位旋转(与1只是异或)和轻微的高尔夫,完整的函数可以是
return'。将[chr(((ord(c)-1)^1)+1)加入stg中的c)
你甚至不需要方括号fwiw,
str.join
很乐意使用任意迭代器,这样gencomp就可以正常工作了。啊,你说得对。这是我在print语句中使用
*[…]
时留下的一部分(不需要生成器)。