[英]How do I tell Python to convert integers into words
我试图告诉 Python 将整数转换为单词。
例子:(用墙上的歌99瓶啤酒)
我用这段代码编写程序:
for i in range(99,0,-1):
print i, "Bottles of beer on the wall,"
print i, "bottles of beer."
print "Take one down and pass it around,"
print i-1, "bottles of beer on the wall."
print
但我不知道如何编写程序以便显示单词(即九十九、九十八等)而不是数字。
我一直在 python 书中绞尽脑汁,我明白也许我只是不理解for
/ if
/ elif
/ else
循环,但我只是在转动我的轮子。
任何人都可以提供任何见解吗? 我不是在寻找直接的答案,尽管这可能会帮助我看到我的问题,但只要能指出我正确的方向就会很棒。
inflect 包可以做到这一点。
https://pypi.python.org/pypi/inflect
$ pip install inflect
接着:
>>>import inflect
>>>p = inflect.engine()
>>>p.number_to_words(99)
ninety-nine
使用可以在 sourceforge 找到的pynum2word模块
>>> import num2word
>>> num2word.to_card(15)
'fifteen'
>>> num2word.to_card(55)
'fifty-five'
>>> num2word.to_card(1555)
'one thousand, five hundred and fifty-five'
这是在 Python 3 中执行此操作的一种方法:
"""Given an int32 number, print it in English."""
def int_to_en(num):
d = { 0 : 'zero', 1 : 'one', 2 : 'two', 3 : 'three', 4 : 'four', 5 : 'five',
6 : 'six', 7 : 'seven', 8 : 'eight', 9 : 'nine', 10 : 'ten',
11 : 'eleven', 12 : 'twelve', 13 : 'thirteen', 14 : 'fourteen',
15 : 'fifteen', 16 : 'sixteen', 17 : 'seventeen', 18 : 'eighteen',
19 : 'nineteen', 20 : 'twenty',
30 : 'thirty', 40 : 'forty', 50 : 'fifty', 60 : 'sixty',
70 : 'seventy', 80 : 'eighty', 90 : 'ninety' }
k = 1000
m = k * 1000
b = m * 1000
t = b * 1000
assert(0 <= num)
if (num < 20):
return d[num]
if (num < 100):
if num % 10 == 0: return d[num]
else: return d[num // 10 * 10] + '-' + d[num % 10]
if (num < k):
if num % 100 == 0: return d[num // 100] + ' hundred'
else: return d[num // 100] + ' hundred and ' + int_to_en(num % 100)
if (num < m):
if num % k == 0: return int_to_en(num // k) + ' thousand'
else: return int_to_en(num // k) + ' thousand, ' + int_to_en(num % k)
if (num < b):
if (num % m) == 0: return int_to_en(num // m) + ' million'
else: return int_to_en(num // m) + ' million, ' + int_to_en(num % m)
if (num < t):
if (num % b) == 0: return int_to_en(num // b) + ' billion'
else: return int_to_en(num // b) + ' billion, ' + int_to_en(num % b)
if (num % t == 0): return int_to_en(num // t) + ' trillion'
else: return int_to_en(num // t) + ' trillion, ' + int_to_en(num % t)
raise AssertionError('num is too large: %s' % str(num))
结果是:
0 zero
3 three
10 ten
11 eleven
19 nineteen
20 twenty
23 twenty-three
34 thirty-four
56 fifty-six
80 eighty
97 ninety-seven
99 ninety-nine
100 one hundred
101 one hundred and one
110 one hundred and ten
117 one hundred and seventeen
120 one hundred and twenty
123 one hundred and twenty-three
172 one hundred and seventy-two
199 one hundred and ninety-nine
200 two hundred
201 two hundred and one
211 two hundred and eleven
223 two hundred and twenty-three
376 three hundred and seventy-six
767 seven hundred and sixty-seven
982 nine hundred and eighty-two
999 nine hundred and ninety-nine
1000 one thousand
1001 one thousand, one
1017 one thousand, seventeen
1023 one thousand, twenty-three
1088 one thousand, eighty-eight
1100 one thousand, one hundred
1109 one thousand, one hundred and nine
1139 one thousand, one hundred and thirty-nine
1239 one thousand, two hundred and thirty-nine
1433 one thousand, four hundred and thirty-three
2000 two thousand
2010 two thousand, ten
7891 seven thousand, eight hundred and ninety-one
89321 eighty-nine thousand, three hundred and twenty-one
999999 nine hundred and ninety-nine thousand, nine hundred and ninety-nine
1000000 one million
2000000 two million
2000000000 two billion
我们采用了一个现有的不错的解决方案(ref)来将数字转换为单词,如下所示:
def numToWords(num,join=True):
'''words = {} convert an integer number into words'''
units = ['','one','two','three','four','five','six','seven','eight','nine']
teens = ['','eleven','twelve','thirteen','fourteen','fifteen','sixteen', \
'seventeen','eighteen','nineteen']
tens = ['','ten','twenty','thirty','forty','fifty','sixty','seventy', \
'eighty','ninety']
thousands = ['','thousand','million','billion','trillion','quadrillion', \
'quintillion','sextillion','septillion','octillion', \
'nonillion','decillion','undecillion','duodecillion', \
'tredecillion','quattuordecillion','sexdecillion', \
'septendecillion','octodecillion','novemdecillion', \
'vigintillion']
words = []
if num==0: words.append('zero')
else:
numStr = '%d'%num
numStrLen = len(numStr)
groups = (numStrLen+2)/3
numStr = numStr.zfill(groups*3)
for i in range(0,groups*3,3):
h,t,u = int(numStr[i]),int(numStr[i+1]),int(numStr[i+2])
g = groups-(i/3+1)
if h>=1:
words.append(units[h])
words.append('hundred')
if t>1:
words.append(tens[t])
if u>=1: words.append(units[u])
elif t==1:
if u>=1: words.append(teens[u])
else: words.append(tens[t])
else:
if u>=1: words.append(units[u])
if (g>=1) and ((h+t+u)>0): words.append(thousands[g]+',')
if join: return ' '.join(words)
return words
#example usages:
print numToWords(0)
print numToWords(11)
print numToWords(110)
print numToWords(1001000025)
print numToWords(123456789012)
结果:
zero
eleven
one hundred ten
one billion, one million, twenty five
one hundred twenty three billion, four hundred fifty six million, seven hundred
eighty nine thousand, twelve
请注意,它适用于整数。 尽管如此,将浮点数分成两个整数部分是微不足道的。
好吧,最简单的方法是列出您感兴趣的所有数字:
numbers = ["zero", "one", "two", "three", "four", "five", ...
"ninety-eight", "ninety-nine"]
( ... 表示您在何处输入其他数字的文本表示。不,Python 不会神奇地为您填写,您必须输入所有这些内容才能使用该技术。)
然后打印数字,只需打印numbers[i]
。 十分简单。
当然,该列表需要大量输入,因此您可能想知道一种简单的生成方法。 不幸的是,英语有很多不规则之处,因此您必须手动输入前二十个 (0-19),但您可以使用规则生成其余多达 99 个。(您也可以生成一些 teens,但仅限其中一些,所以输入它们似乎最容易。)
numbers = "zero one two three four five six seven eight nine".split()
numbers.extend("ten eleven twelve thirteen fourteen fifteen sixteen".split())
numbers.extend("seventeen eighteen nineteen".split())
numbers.extend(tens if ones == "zero" else (tens + "-" + ones)
for tens in "twenty thirty forty fifty sixty seventy eighty ninety".split()
for ones in numbers[0:10])
print numbers[42] # "forty-two"
另一种方法是编写一个函数,每次将正确的字符串放在一起。 同样,您必须对前二十个数字进行硬编码,但之后您可以根据需要轻松地从头开始生成它们。 这会使用更少的内存(一旦您开始使用更大的数字,就会少很多)。
这是上面发布的几个代码示例的重构版本(主要是“开发人员”粘贴的代码。
def int2words(num):
"""Given an int32 number, print it in English.
Parameters
----------
num : int
Returns
-------
words : str
"""
assert (0 <= num)
d = {
0: 'zero', 1: 'one', 2: 'two', 3: 'three', 4: 'four', 5: 'five',
6: 'six', 7: 'seven', 8: 'eight', 9: 'nine', 10: 'ten',
11: 'eleven', 12: 'twelve', 13: 'thirteen', 14: 'fourteen',
15: 'fifteen', 16: 'sixteen', 17: 'seventeen', 18: 'eighteen',
19: 'nineteen', 20: 'twenty',
30: 'thirty', 40: 'forty', 50: 'fifty', 60: 'sixty',
70: 'seventy', 80: 'eighty', 90: 'ninety'
}
h = [100, 'hundred', 'hundred and']
k = [h[0] * 10, 'thousand', 'thousand,']
m = [k[0] * 1000, 'million', 'million,']
b = [m[0] * 1000, 'billion', 'billion,']
t = [b[0] * 1000, 'trillion', 'trillion,']
if num < 20:
return d[num]
if num < 100:
div_, mod_ = divmod(num, 10)
return d[num] if mod_ == 0 else d[div_ * 10] + '-' + d[mod_]
else:
if num < k[0]:
divisor, word1, word2 = h
elif num < m[0]:
divisor, word1, word2 = k
elif num < b[0]:
divisor, word1, word2 = m
elif num < t[0]:
divisor, word1, word2 = b
else:
divisor, word1, word2 = t
div_, mod_ = divmod(num, divisor)
if mod_ == 0:
return '{} {}'.format(int2words(div_), word1)
else:
return '{} {} {}'.format(int2words(div_), word2, int2words(mod_))
这是我的解决方案:) 这是各种早期的解决方案,但我自己开发的 - 也许有人比其他提议更喜欢它。
TENS = {30: 'thirty', 40: 'forty', 50: 'fifty', 60: 'sixty', 70: 'seventy', 80: 'eighty', 90: 'ninety'}
ZERO_TO_TWENTY = (
'zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten',
'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen', 'twenty'
)
def number_to_english(n):
if any(not x.isdigit() for x in str(n)):
return ''
if n <= 20:
return ZERO_TO_TWENTY[n]
elif n < 100 and n % 10 == 0:
return TENS[n]
elif n < 100:
return number_to_english(n - (n % 10)) + ' ' + number_to_english(n % 10)
elif n < 1000 and n % 100 == 0:
return number_to_english(n / 100) + ' hundred'
elif n < 1000:
return number_to_english(n / 100) + ' hundred ' + number_to_english(n % 100)
elif n < 1000000:
return number_to_english(n / 1000) + ' thousand ' + number_to_english(n % 1000)
return ''
它是递归解决方案,可以轻松扩展为更大的数字
听起来您需要使用一个数组,其中num[1] = "one"
、 num[2] = "two"
等等。 然后你可以像你一样循环遍历每个
num = array(["one","two","three","four","five","six","seven","eight","nine","ten"])
for i in range(10,0,-1):
print num[i], "Bottles of beer on the wall,"
print num[i], "bottles of beer."
print "Take one down and pass it around,"
print num[i-1], "bottles of beer on the wall."
print ""
这也适用于前 1000 个数字(Python 3)。 该问题的初学者解决方案,但仍然是一个解决方案......
first_nums = ["", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve",
"thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"]
tens = ["ten", "twenty", "thirty","forty","fifty", "sixty","seventy","eighty","ninety"]
for num in range(1,1001):
if num < 20:
print(first_nums[num])
elif num < 100 and num % 10 == 0:
print(tens[int(num/10 - 1)])
elif num < 1000 and num % 100 == 0:
print(first_nums[int(num/100)] + " hundred")
elif num == 1000:
print("one thousand")
elif num < 100 and num % 10 != 0:
print(tens[int(num//10 - 1)] + " " + first_nums[int(num%10)])
elif num < 1000:
if num%100 < 20:
print(first_nums[int(num//100)] + " hundred and " + first_nums[num%100])
else:
print(first_nums[int(num//100)] + " hundred and " + tens[int(num%100//10 - 1)] + " " + first_nums[int(num%10)])
这在没有任何库的情况下完成了这项工作。 使用递归,它是印度风格。 ——拉维。
def spellNumber(no):
# str(no) will result in 56.9 for 56.90 so we used the method which is given below.
strNo = "%.2f" %no
n = strNo.split(".")
rs = numberToText(int(n[0])).strip()
ps =""
if(len(n)>=2):
ps = numberToText(int(n[1])).strip()
rs = "" + ps+ " paise" if(rs.strip()=="") else (rs + " and " + ps+ " paise").strip()
return rs
print(spellNumber(0.67))
print(spellNumber(5858.099))
print(spellNumber(5083754857380.50))
def numberToText(no):
ones = " ,one,two,three,four,five,six,seven,eight,nine,ten,eleven,tweleve,thirteen,fourteen,fifteen,sixteen,seventeen,eighteen,nineteen,twenty".split(',')
tens = "ten,twenty,thirty,fourty,fifty,sixty,seventy,eighty,ninety".split(',')
text = ""
if len(str(no))<=2:
if(no<20):
text = ones[no]
else:
text = tens[no//10-1] +" " + ones[(no %10)]
elif len(str(no))==3:
text = ones[no//100] +" hundred " + numberToText(no- ((no//100)* 100))
elif len(str(no))<=5:
text = numberToText(no//1000) +" thousand " + numberToText(no- ((no//1000)* 1000))
elif len(str(no))<=7:
text = numberToText(no//100000) +" lakh " + numberToText(no- ((no//100000)* 100000))
else:
text = numberToText(no//10000000) +" crores " + numberToText(no- ((no//10000000)* 10000000))
return text
代码:
>>>def handel_upto_99(number):
predef={0:"zero",1:"one",2:"two",3:"three",4:"four",5:"five",6:"six",7:"seven",8:"eight",9:"nine",10:"ten",11:"eleven",12:"twelve",13:"thirteen",14:"fourteen",15:"fifteen",16:"sixteen",17:"seventeen",18:"eighteen",19:"nineteen",20:"twenty",30:"thirty",40:"fourty",50:"fifty",60:"sixty",70:"seventy",80:"eighty",90:"ninety",100:"hundred",100000:"lakh",10000000:"crore",1000000:"million",1000000000:"billion"}
if number in predef.keys():
return predef[number]
else:
return predef[(number/10)*10]+' '+predef[number%10]
>>>def return_bigdigit(number,devideby):
predef={0:"zero",1:"one",2:"two",3:"three",4:"four",5:"five",6:"six",7:"seven",8:"eight",9:"nine",10:"ten",11:"eleven",12:"twelve",13:"thirteen",14:"fourteen",15:"fifteen",16:"sixteen",17:"seventeen",18:"eighteen",19:"nineteen",20:"twenty",30:"thirty",40:"fourty",50:"fifty",60:"sixty",70:"seventy",80:"eighty",90:"ninety",100:"hundred",1000:"thousand",100000:"lakh",10000000:"crore",1000000:"million",1000000000:"billion"}
if devideby in predef.keys():
return predef[number/devideby]+" "+predef[devideby]
else:
devideby/=10
return handel_upto_99(number/devideby)+" "+predef[devideby]
>>>def mainfunction(number):
dev={100:"hundred",1000:"thousand",100000:"lakh",10000000:"crore",1000000000:"billion"}
if number is 0:
return "Zero"
if number<100:
result=handel_upto_99(number)
else:
result=""
while number>=100:
devideby=1
length=len(str(number))
for i in range(length-1):
devideby*=10
if number%devideby==0:
if devideby in dev:
return handel_upto_99(number/devideby)+" "+ dev[devideby]
else:
return handel_upto_99(number/(devideby/10))+" "+ dev[devideby/10]
res=return_bigdigit(number,devideby)
result=result+' '+res
if devideby not in dev:
number=number-((devideby/10)*(number/(devideby/10)))
number=number-devideby*(number/devideby)
if number <100:
result = result + ' '+ handel_upto_99(number)
return result
结果:
>>>mainfunction(12345)
' twelve thousand three hundred fourty five'
>>>mainfunction(2000)
'two thousand'
#This valid till 4 digit number
numbers={1:'one', 2:'two', 3:'three', 4:'four', 5:'five', 6:'six', 7:'seven', 8:'eight', 9:'nine',
10:'ten', 11:'eleven', 12:'twelve', 13:'thirteen', 14:'fourteen', 15:'fifteen', 16:'sixteen',
17:'seventeen', 18:'eighteen', 19:'nineteen', 20:'twenty', 30:'thirty', 40:'forty', 50:'fifty',
60:'sixty', 70:'seventy', 80:'eighty', 90:'ninety', 100:'hundred', 1000:'thousand'}
def my_fun(num):
list = []
num_len = len(str(num)) - 1
while num_len > 0 and num > 0:
while num_len > 0 and num > 0:
if num in numbers and num < 1000:
list.append(numbers[num])
num_len = 0
elif num < 100:
list.extend([numbers[num - num%10], numbers[num%10]])
num_len = 0
else:
quotent = num//10**num_len # 4567//1000= 4
num = num % 10**num_len #4567%1000 =567
if quotent != 0 :
list.append(numbers[quotent])
list.append(numbers[10**num_len])
else:
list.append(numbers[num])
num_len -= 1
return ' '.join(list)
将数字转换为单词:
这是一个使用字典将数字转换为单词的示例。
string = input("Enter a string: ")
my_dict = {'0': 'zero', '1': 'one', '2': 'two', '3': 'three', '4': 'four', '5': 'five', '6': 'six', '7': 'seven', '8': 'eight', '9': 'nine'}
for item in string:
if item in my_dict.keys():
string = string.replace(item, my_dict[item])
print(string)
我会简单地通过这样做来解决这个问题:
numberText = {
1: 'one', 2: 'two', 3: 'three', 4: 'four', 5: 'five',
6: 'six', 7: 'seven', 8: 'eight', 9: 'nine', 10: 'ten',
11: 'eleven', 12: 'twelve', 13: 'thirteen', 14: 'fourteen',
15: 'fifteen', 16: 'sixteen', 17: 'seventeen', 18: 'eighteen',
19: 'nineteen', 20: 'twenty',
30: 'thirty', 40: 'forty', 50: 'fifty', 60: 'sixty',
70: 'seventy', 80: 'eighty', 90: 'ninety',
100: 'hundred', 1000: 'thousand', 1000000: 'million'
}
def numberToEnglishText(n):
if n == 0:
return 'zero'
if n < 0:
return 'negative ' + numberToEnglishText(-n)
result = ''
for num in sorted(numberText.keys(), reverse=True):
count = int(n/num)
if (count < 1):
continue
if (num >= 100):
result += numberToEnglishText(count) + ' '
result += numberText[num]
n -= count * num
if (n > 0):
result += ' '
return result
我在 Python 3 中创建了一个快速版本的数字到单词转换器,它可以在 [0-99] 范围内工作,而无需使用任何库。 如果您不需要更高的值,此版本可能会很方便。
# converts number-to-word in range [0-99]
def number_to_word(num):
sub_twenty = ('zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight',
'nine', 'ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen',
'sixteen', 'seventeen', 'eighteen', 'nineteen')
tens = {20: 'twenty', 30: 'thirty', 40: 'forty', 50: 'fifty',
60: 'sixty', 70: 'seventy', 80: 'eighty', 90: 'ninety'}
# if it is less than 20 directly converts its value from the list
if num < 20:
return sub_twenty[num]
# if its order of 10 gets from the dict
elif num % 10 == 0:
return tens[num]
# if it has any value in units digit gets both
else:
quo = num // 10 # quotient
quo = tens[quo * 10] # scale and get value from dict
rem = num % 10 # remainder
rem = sub_twenty[rem] # get its word format
return quo + " " + rem
您必须使用字典/数组。 例如 :
to_19= ['zero','one','two','three','four','five','six','seven','eight','nine'..'nineteen']
tens = ['twenty'...'ninety']
您可以通过执行以下操作来生成数字字符串,例如:
if len(str(number)) == 2 and number > 20:
word_number = tens[str(number)[0]]+' '+units[str(number)[0]]
你必须检查最后一个数字是否不是零等等......经典的值检查。
它提醒了一个项目欧拉挑战(问题17)..你应该尝试找到一些解决方案
希望能帮助到你
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.