Python中的字母移动程序
假设我有一个字母表的列表:
ALPHABET = ['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']
然后假设我们要移动的位置是
0, 2, 19
如果输入是一个字符串
string = "xyz"
我想用上面的移动位置0, 2, 19来移动这三个字符。
也就是说,把 'x'
向右移动0次,把 'y'
向右移动2次,把 'z'
向右移动19次。
我想到的唯一方法就是使用类似于列表的 index()
函数。
我还发现了另一个问题。如果我把 'z'
向右移动19次,会出现 list index out of range
的错误。如果 'z'
向右移动19次,我希望它变成 's'
,这就意味着在列表中转一圈后再从头开始。'y'
也是一样,如果我把它向右移动2次,我希望它变成 'a'
,等等……
有什么建议可以使用吗?
3 个回答
编辑:我刚意识到我可能在回答一个完全不同的问题,因为我脑子里对“shift”这个词的理解不太准确。所以我不是在生成新的字母,而是在生成一个全新的字母表。随便你们指着我笑。
要解决超出范围的问题,你需要使用取模运算符 %
,这样可以让数字“循环回去”。你可以把它和切片结合起来,来实现你的位移。
ALPHABET = ['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']
inputstring = "XYZ"
def shift(inputstr, shift1, shift2, shift3):
new_alphabet = list(ALPHABET)
shifts = [shift1, shift2, shift3]
for i in range(0,3):
inputchar = inputstr[i]
i1 = new_alphabet.index(inputchar)
i1_adjust = (i1 + shifts[i]) % len(new_alphabet)
temp_alphabet = new_alphabet[:i1] + new_alphabet[i1+1:]
new_alphabet = temp_alphabet[:i1_adjust] + [inputchar] + temp_alphabet[i1_adjust:]
print new_alphabet
# We call it here.
shift(inputstring,0,2,19)
我们基本上是在找出字符的位置,然后把位移的数量加到这个位置上。接着,我们从字母表中取出那个字符,并向前移动 i1_adjust
个位置到新的位置。我们在那个位置把字母表分开,插入字符,然后再把它们粘合在一起。如果把 shift1, shift2, shift3
改成一个位移位置的列表,代码可能会更优雅,但这个概念的证明已经在这里了。
我可以这样解决吗:如果你不喜欢这个解决方案,请在评论里告诉我,我会把它删掉。(不要直接给我差评)
#!/usr/bin/python
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']
def shift_right(char, shift_inx):
dic1 = dict(zip(alpha, range(26)))
dic2 = dict(zip(range(26), alpha))
total = len(alpha)
nxt_inx = dic1[char] + shift_inx
if nxt_inx <= 25:
return dic2[nxt_inx]
else:
return dic2[nxt_inx % total]
def main():
for x,y in [('X', 0), ('Y', 2), ('Z', 19)]:
print '%s => %s => %s' % ( x, y, shift_right(x, y))
if __name__ == '__main__':
main()
输出:
X => 0 => X
Y => 2 => A
Z => 19 => S
或者
#!/usr/bin/python
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']
def shift_right(char, shift_inx):
total = len(alpha)
nxt_inx = alpha.index(char) + shift_inx
if nxt_inx <= 25:
return alpha[nxt_inx]
else:
return alpha[nxt_inx % total]
def main():
for x,y in [('X', 0), ('Y', 2), ('Z', 20)]:
print '%s => %s => %s' % ( x, y, shift_right(x, y))
if __name__ == '__main__':
main()
我的方法比TheSoundDefense的更简单,但在输入三个字母,比如“xyz”时效果很好。(我猜你可以想个办法来确保他们确实输入了三个字母)
我主要用的工具是索引函数,它可以在列表中找到一个项目,并告诉我这个项目的位置编号。然后我把这个编号加上你给的数字。接着,我用这个和长度进行除法运算,取余数。我不在乎它能除多少次,我只想要余数,因为余数能告诉我这个字母在字母表中的位置。最后,我把字母替换掉,然后打印出来。
ALPHABET = ['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']
print "Please enter three letters"
x = list(raw_input("> ").upper())
length = len(ALPHABET)
first_letter = ALPHABET.index(x[0])
first_letter = (first_letter + 0) % length
x[0] = ALPHABET[first_letter]
second_letter = ALPHABET.index(x[1])
second_letter = (second_letter + 2) % length
x[1] = ALPHABET[second_letter]
third_letter = ALPHABET.index(x[2])
third_letter = (third_letter + 19) % length
x[2] = ALPHABET[third_letter]
print ''.join(x)