Как мне сказать Python преобразовать целые числа в слова
Я пытаюсь сказать 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
Но я не могу понять, как написать программу, чтобы вместо цифр отображались слова (девяносто девять, девяносто восемь и т. Д.).
Я ломал голову в книге о питоне, которую я имею, я понимаю, что, может быть, я просто не понимаю, for
/if
/elif
/else
пока нет петель, но я просто вращаю свои колеса.
Может ли кто-нибудь предоставить какое-либо понимание? Я не ищу прямого ответа, хотя это может помочь мне увидеть мою проблему, просто что-нибудь, чтобы указать мне правильное направление, было бы здорово.
17 ответов
Пакет inflect может сделать это.
https://pypi.python.org/pypi/inflect
$ pip install inflect
а потом:
>>>import inflect
>>>p = inflect.engine()
>>>p.number_to_words(99)
ninety-nine
Используйте модуль pynum2word, который можно найти в sourceforge
>>> 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. (Вы также можете сгенерировать некоторых подростков, но только некоторые из них, так что, кажется, проще всего их ввести.)
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"
Другой подход - написать функцию, которая каждый раз собирает правильную строку. Опять же, вам придется жестко кодировать первые двадцать чисел, но после этого вы сможете легко сгенерировать их с нуля по мере необходимости. Это использует немного меньше памяти (намного меньше, когда вы начинаете работать с большими числами).
Вы можете использовать библиотеку python-n2w, просто сделайте
pip install n2w
тогда просто
print(n2w.convert(your-number-here))
И тут приходит мое решение:) Это различные из более ранних решений, но разработанные мной самим - возможно, кому-то понравится больше, чем другим предложениям.
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 ''
Это рекурсивное решение, которое можно легко расширить для больших чисел
Это делает работу без какой-либо библиотеки. Используется рекурсия и это индийский стиль. Рави.
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 = ", один, два, три, четыре, пять, шесть, семь, восемь, девять, десять, одиннадцать, двенадцать, тринадцать, четырнадцать, пятнадцать, шестнадцать, семнадцать, восемнадцать, девятнадцать, двадцать".split(',') tens = "десять, двадцать, тридцать, сорок, пятьдесят, шестьдесят, семьдесят, восемьдесят, девяносто".split(',') text = "" if len(str(no))<=2: if(no<20): text = ones[no] else: text = десятки [no//10-1] +" " + ones[(no %10)] elif len(str(no))==3: text = ones[no//100] +"сотня" + numberToText(no- ((no//100)* 100)) elif len(str(no))<=5: text = numberToText(no//1000) +"тысяча" + numberToText(no- ((no//1000)* 1000)) elif len(str(no))<=7: text = numberToText(no//100000) +" lakh " + numberToText(no- ((№ //100000)* 100000)) else: text = numberToText(№ //0000000) + "кроры" + numberToText (no- ((№ //10000000)* 10000000)) возвращаемый текст
Я бы решил эту проблему, просто сделав это:
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
Похоже, вам нужно использовать массив, где 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 ""
Вот реорганизованная версия нескольких примеров кода, размещенных выше (в основном код, вставленный "разработчиком").
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_))
Код для этого:
>>>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'
Это работает и для первых 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)])
Преобразование чисел в слова:
вот пример, в котором числа были преобразованы в слова с помощью словаря.
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)
#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)
Я создал быструю версию преобразователя чисел в слова на 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). Вы должны попытаться найти некоторые решения по этому поводу.
Надеюсь, поможет