1

我是 Python 新手,对模数有疑问。

这是代码:

for i in range(ord('a'), ord('z')+1):
    print chr(((i+2) % 97) + 97 )

预期的结果是cdef...a。但是,一旦我们到达z.

4

5 回答 5

6

因为 97 不是您想要换行的 - 您想要换行ord('z')= 122,然后添加ord('a')(97) 的值。

您真正需要做的全部数学运算是转换为偏移量,然后返回到集合。例如...

for i in range(ord('z') - ord('a') + 1): # equivalent to range(26); i.e. 0-25
    print chr(((i+2) % 26) + ord('a')) # results in 2+97 'c', 3+97 'd', etc.

您现有代码不起作用的原因是因为您i+2将始终大于 97(因为您iord('a')97 开始,然后从那里上升),所以% 97实际上是 just - 97,因此您的打印行实际上是这样的:

print chr(((i+2) - 97) + 97 )

这减少到...

print chr((i+2) - 97 + 97)

这显然只是print chr(i+2)

于 2012-10-23T06:51:34.707 回答
3

您应该以 26 为模(英文字母表中的字母数)。此代码将起作用:

for i in range(ord('a'), ord('z') + 1):
   j = i - ord('a')
   print chr(ord('a') + (j + 2) % 26)

解释

考虑这个索引模板:

A + (j + B) % C

它将不同的值映射j到 range A … (A + C - 1)。最初,您选择了A = 97and C = 97,因此您将映射到 range 97 … 193。我选择了A = ord('a') = 97and C = 26,所以我映射到范围97 … 122,即ord('a') … ord('z')

现在关于偏移量,B. 您想向左旋转两个位置,因此您正确选择了B = 2. 但是,为了使它起作用,a因为第一个字母必须0在旋转之前进行编码。因此j = i - ord('a')

于 2012-10-23T06:52:47.993 回答
1

其他人已经回答了您的代码有什么问题。我想提出一个根本不需要处理模数的解决方案。我认为这是一种更简洁的方法,因为您不必处理使用 and 来回转换的ord细节chr

即使您正在处理字符代码不是全部按顺序排列的外国字母,它也可以工作。

>>> from string import ascii_lowercase
>>> from collections import deque
>>> chrs = deque(ascii_lowercase)
>>> chrs.rotate(-2)
>>> print "".join(chrs)
cdefghijklmnopqrstuvwxyzab

如果您打算将其用于某种翻译或编码,只需构建一个 dict 即可:

>>> tr = dict(zip(ascii_lowercase, chrs))
>>> "".join(tr.get(x, x) for x in "abcd xyz")
'cdef zab'
于 2012-10-23T07:37:39.910 回答
1

在处理 mod 时,从 1 以外的数字循环可能会令人困惑。这是您的代码重构为使用 1 作为起点。

for i in range(ord('a'), ord('z')+1):
    print chr( (i-97+2) % 26) + 97 ) #Subtract 97, do our modulo and shift, then add 97
于 2012-10-23T07:02:34.810 回答
1

您需要将值调整为 0-26 范围,修改它,应用 mod,然后移回正确的字符范围。这里有多个步骤

for i in range(ord('a'), ord('z')+1):
    idx = i - ord('a')
    mod_idx = ( idx + 2 ) % 26
    c = chr( mod_idx + ord('a') )
    print( chr(c) )

这在单行中也是一样的(IMO 太丑了)

for i in range(ord('a'), ord('z')+1):
    print( chr((( i - ord('a')) + 2 ) % 26 + ord('a')) )
于 2012-10-23T07:00:32.117 回答