我试图理解程序中的while
循环和sorted
调用将数字转换为下面的罗马数字。
numerals = { 1 : "I", 4 : "IV", 5 : "V", 9 : "IX", 10 : "X", 40 : "XL",
50 : "L", 90 : "XC", 100 : "C", 400 : "CD", 500 : "D", 900 : "CM", 1000 : "M" }
num = 58 # LVIII
roman = ''
for k, v in sorted(numerals.items(), reverse=True):
while num >= k:
roman += v
num -= k
print(roman)
问题:1)如果使用numerals.items()
而不是sorted(numerals.items(), reverse=True)
,为什么代码不起作用? (例如,58将导致IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
而不是LVIII
。)当在该行上使用断点时,无论有无sorted
,它看起来都是相同的。
2)第一个罗马数字是L
。为什么?调试时我注意到它从1000开始倒数。当它达到50时,我看到roman == 'L'
。该代码测试num >= k
。 1000(M)也大于58.为什么条件num >= k
导致L
成为第一位数?
sorted(numerals.items(), reverse=True)
不仅意味着排序,而且意味着反向排序。关键点是reverse=True
。因为我们必须先与最大的罗马人相提并论。从M
到I
,而不是从I
到M
。"The logic says num>=k. 1000,M is also greater than num 58."
我想你在这里有误解。对于while num>=k:
,它找到的数量少于或等于num,不大,所以L
将是第一个。希望能帮到你。
没有sorted
,循环将以1, 'I'
开头。然后将尽可能多地使用它。在这种情况下,这将导致58 I
s。 (然后继续上4, 'IV'
,5, 'V'
等,但num
将为0.)使用sorted
,循环开始于1000, 'M'
,然后是900, 'CM'
等(在调试器中看不到排序的原因是sorted
returns a new list。)当它到达50, 'L'
时,while循环测试58 >= 50
(你的观察中的顺序错误),这是真的。然后它将num
设置为8,将roman
设置为'L'
。然后它继续循环以获得剩余的数字。
# num=58# answer> LVIII
num = 58
numerals = { 1 : "I", 4 : "IV", 5 : "V", 9 : "IX", 10 : "X", 40 : "XL",
50 : "L", 90 : "XC", 100 : "C", 400 : "CD", 500 : "D", 900 : "CM", 1000 : "M" }
roman=''
# reserve numerals
for k, v in sorted(numerals.items(), reverse=True):
while num>=k:
roman=roman+v
num = num - k
print(roman)