Python 出于某种原因,每当在if语句中检查条件时,列表的值chars就会重置,从而中断程序
我正在尝试创建一个函数,该函数接受字符串并运行以下加密算法:字母表中奇数位置I处的每个字符将使用位置I+1处的字符加密,偶数位置I处的每个字符将使用位置I-1处的字符加密。换句话说,“a”用“b”加密,“b”用“a”,c用“d”,d用“c”加密,等等。小写字符应保持小写,大写字符应保持大写。换句话说,“bob”将输出为“apa” 虽然我最终解决了这个问题,但我仍然不知道为什么在我的条件中使用chars[I]而不是stg[I]会破坏程序。从我的观察来看,这个列表似乎是以随机间隔重新设置的。有人能解释为什么交换变量修复了我的程序吗?谢谢大家! 坏程序: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]会破坏程序。从我的观察来看,这个列表似乎是以随机间隔重新设置的。有人能解
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
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语句中使用*[…]
时留下的一部分(不需要生成器)。