整数转罗马while循环解释-Python
Integer to Roman while loop explanation-Python
我试图理解程序中的 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
.[=24= 的情况下都保持不变]
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'
。然后继续循环得到剩余的数字。
Python3:
# 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)
我试图理解程序中的 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
.[=24= 的情况下都保持不变]
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'
。然后继续循环得到剩余的数字。
Python3:
# 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)