I have a function roman(x)
that takes an int
(>= 1
) and returns the roman numeral as a string. I have achieved a working example with:
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'
I am asking how to convert the for loop:
y = ""
for val, sym in L:
y = sym*(x//val)
x -= val*(x//val)
return y
Into a list comprehension
return "".join([ ... ])
L
Does not need to be embedded into the list comprehension, and can remain as is. Such that the function is in this form:
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([ ... ])
CodePudding user response:
If you don't mind recursion, this is actually a pretty good use case for it.
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'
CodePudding user response:
Version using 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
It's scary, it's unreadable. Don't use it
CodePudding user response:
Since Python lacks the power of pointers, to use "".join([])
as your requirement, I think this code can be your solution
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')]
L = dict(L)
x = [x]
def custum_mul(x,k):
temp = x[0]//k
x[0]-= k*(x[0]//k)
return temp
y = "".join([v*(custum_mul(x,k)) for k,v in L.items()])
return y
out = roman(399)
print(out) # CCCXCIX
However, it's long, complex, and hard to understand so don't use it.