对 int 到罗马数字的列表理解
List comprehension for int to roman numeral
我有一个函数 roman(x)
,它将 int
(>= 1
) 和 returns 罗马数字作为字符串。我已经实现了一个工作示例:
def roman(x: int) -> str:
"""Convert into to roman numeral"""
L = [(1000, 'M'), (900, 'CM'), (500, 'D'), (400, 'CD'),
(100, 'C'), (90, 'XC'), (50, 'L'), (40, 'XL'),
(10, 'X'), (9, 'IX'), (5, 'V'), (4, 'IV'), (1, 'I')]
y = ""
for val, sym in L:
y += sym*(x//val)
x -= val*(x//val)
return y
>>> roman(399)
'CCCXCIX'
我问的是如何转换for循环:
y = ""
for val, sym in L:
y += sym*(x//val)
x -= val*(x//val)
return y
进入列表理解
return "".join([ ... ])
L
不需要嵌入到列表理解中,可以保持原样。这样函数就是这样的形式:
def roman(x: int) -> str:
"""Convert into to roman numeral"""
L = [(1000, 'M'), (900, 'CM'), (500, 'D'), (400, 'CD'),
(100, 'C'), (90, 'XC'), (50, 'L'), (40, 'XL'),
(10, 'X'), (9, 'IX'), (5, 'V'), (4, 'IV'), (1, 'I')]
# Return list comprehension as a string
return "".join([ ... ])
版本使用functools.reduce
from functools import reduce
def roman(x: int) -> str:
"""Convert into to roman numeral"""
L = [(1000, 'M'), (900, 'CM'), (500, 'D'), (400, 'CD'),
(100, 'C'), (90, 'XC'), (50, 'L'), (40, 'XL'),
(10, 'X'), (9, 'IX'), (5, 'V'), (4, 'IV'), (1, 'I')]
return reduce(lambda s, c: (s[0] + c[1]*(s[1]//c[0]), s[1] - c[0]*(s[1]//c[0])), L, ("", x))[0]
print(roman(399)) # CCCXCIX
可怕,不可读。不要使用它
如果您不介意递归,这实际上是一个非常好的用例。
L = [(1000, 'M'), (900, 'CM'), (500, 'D'), (400, 'CD'),
(100, 'C'), (90, 'XC'), (50, 'L'), (40, 'XL'),
(10, 'X'), (9, 'IX'), (5, 'V'), (4, 'IV'), (1, 'I')]
def roman(num):
if num == 0: # Base case: when we reach zero, return empty string
return ''
# Recursive step: iterate over values and their characters
for v, n in L:
if num >= v: # If their difference is positive, we recurse
return n + roman(num - v) # We append the result to the numeral
roman(399)
>> 'CCCXCIX'
def roman(x: int) -> str:
"""Convert into to roman numeral"""
L = [(1000, 'M'), (900, 'CM'), (500, 'D'), (400, 'CD'),
(100, 'C'), (90, 'XC'), (50, 'L'), (40, 'XL'),
(10, 'X'), (9, 'IX'), (5, 'V'), (4, 'IV'), (1, 'I')]
return ''.join([(sym*(x//val), (x:=x-val*(x//val)))[0] for val, sym in L])
print(roman(399)) # CCCXCIX
我有一个函数 roman(x)
,它将 int
(>= 1
) 和 returns 罗马数字作为字符串。我已经实现了一个工作示例:
def roman(x: int) -> str:
"""Convert into to roman numeral"""
L = [(1000, 'M'), (900, 'CM'), (500, 'D'), (400, 'CD'),
(100, 'C'), (90, 'XC'), (50, 'L'), (40, 'XL'),
(10, 'X'), (9, 'IX'), (5, 'V'), (4, 'IV'), (1, 'I')]
y = ""
for val, sym in L:
y += sym*(x//val)
x -= val*(x//val)
return y
>>> roman(399)
'CCCXCIX'
我问的是如何转换for循环:
y = ""
for val, sym in L:
y += sym*(x//val)
x -= val*(x//val)
return y
进入列表理解
return "".join([ ... ])
L
不需要嵌入到列表理解中,可以保持原样。这样函数就是这样的形式:
def roman(x: int) -> str:
"""Convert into to roman numeral"""
L = [(1000, 'M'), (900, 'CM'), (500, 'D'), (400, 'CD'),
(100, 'C'), (90, 'XC'), (50, 'L'), (40, 'XL'),
(10, 'X'), (9, 'IX'), (5, 'V'), (4, 'IV'), (1, 'I')]
# Return list comprehension as a string
return "".join([ ... ])
版本使用functools.reduce
from functools import reduce
def roman(x: int) -> str:
"""Convert into to roman numeral"""
L = [(1000, 'M'), (900, 'CM'), (500, 'D'), (400, 'CD'),
(100, 'C'), (90, 'XC'), (50, 'L'), (40, 'XL'),
(10, 'X'), (9, 'IX'), (5, 'V'), (4, 'IV'), (1, 'I')]
return reduce(lambda s, c: (s[0] + c[1]*(s[1]//c[0]), s[1] - c[0]*(s[1]//c[0])), L, ("", x))[0]
print(roman(399)) # CCCXCIX
可怕,不可读。不要使用它
如果您不介意递归,这实际上是一个非常好的用例。
L = [(1000, 'M'), (900, 'CM'), (500, 'D'), (400, 'CD'),
(100, 'C'), (90, 'XC'), (50, 'L'), (40, 'XL'),
(10, 'X'), (9, 'IX'), (5, 'V'), (4, 'IV'), (1, 'I')]
def roman(num):
if num == 0: # Base case: when we reach zero, return empty string
return ''
# Recursive step: iterate over values and their characters
for v, n in L:
if num >= v: # If their difference is positive, we recurse
return n + roman(num - v) # We append the result to the numeral
roman(399)
>> 'CCCXCIX'
def roman(x: int) -> str:
"""Convert into to roman numeral"""
L = [(1000, 'M'), (900, 'CM'), (500, 'D'), (400, 'CD'),
(100, 'C'), (90, 'XC'), (50, 'L'), (40, 'XL'),
(10, 'X'), (9, 'IX'), (5, 'V'), (4, 'IV'), (1, 'I')]
return ''.join([(sym*(x//val), (x:=x-val*(x//val)))[0] for val, sym in L])
print(roman(399)) # CCCXCIX