最近在用《Dive to Python》学习Python 2.7时遇到罗马数字和阿拉伯数字互换的示例:
romanNumeralMap = (('M',1000),
('CM',900),
('D',500),
('CD',400),
('C',100),
('XC',90),
('L',50),
('XL',40),
('X',10),
('IX',9),
('V',5),
('IV',4),
('I',1))
def toRoman(n):
result = ""
for numeral, integer in romanNumeralMap:
while n >= integer:
result += numeral
n -= integer
return result
def fromRoman(s):
result = 0
index = 0
for numeral, integer in romanNumeralMap:
while s[index:index+len(numeral)] == numeral:
result += integer
index += len(numeral)
return result
print toRoman(1356)
print fromRoman('MCMLXXII')
在这段代码执行过程中:
for numeral, integer in romanNumeralMap:
while s[index:index+len(numeral)] == numeral:
result += integer
index += len(numeral)
第二次循环,s[index:index+len(numeral)]
返回的结果是 CM
但我的理解是第一次执行之后index = 1
那么index + len(numeral) = 2
,故此时的截取结果应当是C
,为什么这次循环运行结果是CM
?求助,我的逻辑哪里有问题?
romanNumeralMap 中('CM',900)排在('C',100)前面。迭代到('CM',900)这个元素的时候,并跑完while里面逻辑的时候,indexindex + len(numeral) 已经等于3了。
第一次执行之后取了参数字符串中的第一个字符M
,index变成1。第二次,在while
的循环比较过程中,发现CM
是一个单位,所以取了参数中的CM
,然后更新index为3。
这里的关键点是while
循环,它会依次比较romanNumeralMap
中定义的罗马数字单位,并且以找到的第一个为准。因为其中CM
的定义在C
之前,所以先找到的是CM
,所以第二次截取的是CM
,而不是你认为的C
。