python中的移位n个字母
我试图解决一个udacity编程问题,如下所示: 编写一个过程,shift_n_letters,它以小写字母a-z和整数n作为输入,并在步骤中返回字母n 后面是字母表。请注意,“a”跟在“z”后面,n可以是正、负或零 代码:python中的移位n个字母,python,algorithm,Python,Algorithm,我试图解决一个udacity编程问题,如下所示: 编写一个过程,shift_n_letters,它以小写字母a-z和整数n作为输入,并在步骤中返回字母n 后面是字母表。请注意,“a”跟在“z”后面,n可以是正、负或零 代码: def shift_n_letters(letter, n): result = chr(ord(letter) + n) if ord(result) > 122: return chr(96+ ord(result) - 122) return
def shift_n_letters(letter, n):
result = chr(ord(letter) + n)
if ord(result) > 122:
return chr(96+ ord(result) - 122)
return result
print shift_n_letters('s', 1)
#>>> t
print shift_n_letters('s', 2)
#>>> u
print shift_n_letters('s', 10)
#>>> c
print shift_n_letters('a', -1)
#>>> z
我得到了
t,u,c
和`as结果。请有人帮我找出哪里出了问题。谢谢。只需取字母表长度的模数:
def shift_n_letters(letter, n):
n_ = n % 26
result = chr(ord(letter) + n_)
if ord(result) > 122:
result = chr(ord(result) - 26)
return result
它搞砸了,因为(我认为)它使用的是unicode系统中的字母顺序,显然“在a之前”
使现代化
我想出了一个简单得多的算法
def shift_n_letters(letter, n):
return chr((ord(letter) - 97 + n % 26) % 26 + 97)
算法
ord(letter)-97
——通过对字符的unicode顺序进行减法,将letter
放在0-25范围内+n%26
——添加偏移,针对z和a之间的周期边界进行调整%26
——如果移位导致订单离开范围0-25,则取模数26+97
——添加a的unicode顺序(之前已减去)chr(…)
——返回刚才计算的unicode顺序索引的字符只需取字母表长度的模数
n
:
def shift_n_letters(letter, n):
n_ = n % 26
result = chr(ord(letter) + n_)
if ord(result) > 122:
result = chr(ord(result) - 26)
return result
它搞砸了,因为(我认为)它使用的是unicode系统中的字母顺序,显然“在a之前”
使现代化
我想出了一个简单得多的算法
def shift_n_letters(letter, n):
return chr((ord(letter) - 97 + n % 26) % 26 + 97)
算法
ord(letter)-97
——通过对字符的unicode顺序进行减法,将letter
放在0-25范围内+n%26
——添加偏移,针对z和a之间的周期边界进行调整%26
——如果移位导致订单离开范围0-25,则取模数26+97
——添加a的unicode顺序(之前已减去)chr(…)
——返回刚才计算的unicode顺序索引的字符避免字母编码错误的问题
def shift_n_letters(letter, n):
result = ord(letter) + n
while result > ord('z'):
result -= 26
while result < ord('a'):
result += 26
return chr(result)
两者都适用于
n
的任何值,以避免字母的错误代码问题
def shift_n_letters(letter, n):
result = ord(letter) + n
while result > ord('z'):
result -= 26
while result < ord('a'):
result += 26
return chr(result)
两者都适用于
n
的任何值,使用maketrans
避免与chr
或ord
相关的所有麻烦。从:
string.maketrans(从、到)
返回适合传递到translate()的转换表,该表将把from中的每个字符映射到to中相同位置的字符中;from和to必须具有相同的长度
您的用例示例:
import string
def shift_n_letters(text, n):
intab = string.ascii_lowercase # "abcdefghijklmnopqrstuvwxyz"
outtab = intab[n % 26:] + intab[:n % 26] # alphabet shifted by n
trantab = string.maketrans(intab, outtab) # translation made b/w patterns
return text.translate(trantab) # text is shifted to right
它在实践中的工作原理:
>>> shift_n_letters('a',-1)
'z'
>>> shift_n_letters('s',10)
'c'
>>> shift_n_letters('hello',10)
'rovvy'
这样做的优点是处理比单个字符更复杂的字符串,并且可以处理任何
n
使用maketrans
避免与chr
或ord
相关的所有麻烦。从:
string.maketrans(从、到)
返回适合传递到translate()的转换表,该表将把from中的每个字符映射到to中相同位置的字符中;from和to必须具有相同的长度
您的用例示例:
import string
def shift_n_letters(text, n):
intab = string.ascii_lowercase # "abcdefghijklmnopqrstuvwxyz"
outtab = intab[n % 26:] + intab[:n % 26] # alphabet shifted by n
trantab = string.maketrans(intab, outtab) # translation made b/w patterns
return text.translate(trantab) # text is shifted to right
它在实践中的工作原理:
>>> shift_n_letters('a',-1)
'z'
>>> shift_n_letters('s',10)
'c'
>>> shift_n_letters('hello',10)
'rovvy'
这样做的优点是处理比单个字符更复杂的字符串,并且可以处理任何
n
您需要取n模26,写为n%26,其中您当前只有n:result=chr(ord(字母)+n%26)。这样您就可以正确地环绕,而不是遍历其余的unicode字符。您需要取n模26,写为n%26,其中您当前只有n:result=chr(ord(字母)+n%26)。这样您就可以正确地进行换行,而不是遍历其余的unicode字符。我认为您可以这样做:
def shift_n_letters(letter, n):
# Create an array of characters from 'a' to 'z'
char_array = [chr(i) for i in range(97, 123)]
result = ""
for ch in list(message):
# Get the corresponding index in char_array and add 'n' to it.
# Also remember to % 26, which is length of char_array
index = (char_array.index(ch) + n) % 26
# And append to result string the newly computed character
result += char_array[index]
return result
希望能有所帮助。我想你可以这样做:
def shift_n_letters(letter, n):
# Create an array of characters from 'a' to 'z'
char_array = [chr(i) for i in range(97, 123)]
result = ""
for ch in list(message):
# Get the corresponding index in char_array and add 'n' to it.
# Also remember to % 26, which is length of char_array
index = (char_array.index(ch) + n) % 26
# And append to result string the newly computed character
result += char_array[index]
return result
希望这能有所帮助。提示:使用提示:使用这样更改变量的值通常是个坏主意。我建议将
n
设置为等于n%26
@信号时,将其更改为其他值。为什么这是个坏主意?如果变量被传递到函数,覆盖保持在函数的范围内,并且由于它是一个小函数,n只有一个用途,那么会造成什么危害?我意识到可读性问题可能会出现在更大的范围内,但PEP8会抱怨吗?或者我遗漏了什么?好吧,这并没有违反政治公众人物第8条,但由于你已经提到的原因,这是一个很好的做法。对。感谢您的评论,我更新了答案:)@可编写脚本的字母a-z位于Unicode字母表中第97和122项之间n
可能是任何疯狂的大数字,但由于a-z字母表有周期性边界,您只需将%26
移到n
,因为向前移动145或15个字符没有任何区别。然后获得字母的unicode字母顺序,并将其添加到\u n
中,但如果得到的字符超出a-z范围(ord(result)>122
),则从结果中删除一个字母长度的索引。我对代码进行了一些更新,使其更易于理解。这样更改变量的值通常不是一个好主意。我建议将n
设置为等于n%26
@信号时,将其更改为其他值。为什么这是个坏主意?如果变量被传递到函数,覆盖保持在函数的范围内,并且由于它是一个小函数,n只有一个用途,那么会造成什么危害?我意识到可读性问题可能会出现在更大的范围内,但PEP8会抱怨吗?或者我遗漏了什么?好吧,这并没有违反政治公众人物第8条,但由于你已经提到的原因,这是一个很好的做法。对。感谢您的评论,我更新了答案:)@可编写脚本的字母a-z位于Unicode字母表的第97和122项之间