Python 如何改进这个number2words脚本 导入系统 单词={ 1:"一",, 二:"两",, 三:"三",, 四:"四",, 五:"五",, 六:"六",, 7:"七",, 八:'八',, 九:'九',, 10:‘十’, 11:"十一",, 12:"十二",, 13:‘十三’, 14:‘十四’, 15:‘十五’, 16:‘十六’, 17:‘十七’, 18:‘十八’, 19:‘十九’ } 十个=[ '', ‘二十’, “三十”, ‘四十’, “五十”, “六十”, ‘七十’, “八十”, “九十”, ] 占位符=[ '', ‘千’, "百万",, "亿",, "万亿",, “万亿” ] #segMag=分段幅值(从1开始) def转换器(编号): 返回“”。join([words[int(number[0])],'hund',convertdou(number[1:3]))#convertdou(number[1:3])) def转换器(编号): #如果十几岁或更少 如果int(数字[0])==1: 返回单词[int(number)] #二十五 其他: 返回十个[int(数字[0])-1]+'-'+字[int(数字[1])] 如果名称=“\uuuuu main\uuuuuuuu”: 字符串=[] 数字段=[] 数字=系统argv[1] 如果int(数字)
警告:我完全是python新手。我知道可能有很多更有效的做事方式。如果有人给我指点,我将不胜感激Python 如何改进这个number2words脚本 导入系统 单词={ 1:"一",, 二:"两",, 三:"三",, 四:"四",, 五:"五",, 六:"六",, 7:"七",, 八:'八',, 九:'九',, 10:‘十’, 11:"十一",, 12:"十二",, 13:‘十三’, 14:‘十四’, 15:‘十五’, 16:‘十六’, 17:‘十七’, 18:‘十八’, 19:‘十九’ } 十个=[ '', ‘二十’, “三十”, ‘四十’, “五十”, “六十”, ‘七十’, “八十”, “九十”, ] 占位符=[ '', ‘千’, "百万",, "亿",, "万亿",, “万亿” ] #segMag=分段幅值(从1开始) def转换器(编号): 返回“”。join([words[int(number[0])],'hund',convertdou(number[1:3]))#convertdou(number[1:3])) def转换器(编号): #如果十几岁或更少 如果int(数字[0])==1: 返回单词[int(number)] #二十五 其他: 返回十个[int(数字[0])-1]+'-'+字[int(数字[1])] 如果名称=“\uuuuu main\uuuuuuuu”: 字符串=[] 数字段=[] 数字=系统argv[1] 如果int(数字),python,Python,警告:我完全是python新手。我知道可能有很多更有效的做事方式。如果有人给我指点,我将不胜感激 编辑:该代码目前仅适用于数字计数为三的倍数的数字。如果能给我一个优雅的解决方法的建议,我将不胜感激。谢谢。我想到了两个改进: 40的拼写是“四十”,而不是“四十” 你的程序需要单元测试 看看Python和模块。可能会有一些帮助。不过有点过时了——2005年5月4日。您不能将数字从左到右分组为“段”。范围(0,len(),3)将无法正常工作。您必须编写插入数字分隔符的相同算法。从右侧开始,拾取数字
编辑:该代码目前仅适用于数字计数为三的倍数的数字。如果能给我一个优雅的解决方法的建议,我将不胜感激。谢谢。我想到了两个改进:
- 40的拼写是“四十”,而不是“四十”
- 你的程序需要单元测试
看看Python和模块。可能会有一些帮助。不过有点过时了——2005年5月4日。您不能将数字从左到右分组为“段”。
范围(0,len(),3)
将无法正常工作。您必须编写插入数字分隔符的相同算法。从右侧开始,拾取数字段
剩下的(在左边,明白吗?)将是1、2或3位数字。有convertTrio和convertDuo,它们分别处理3位和2位数字。某个地方有一个转换一位数的函数(看不见)
如果这不是家庭作业,那么,这里有一个合适的数字聚类算法
import sys
words = {
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'
}
tens = [
'',
'twenty',
'thirty',
'forty',
'fifty',
'sixty',
'seventy',
'eighty',
'ninety',
]
placeholders = [
'',
'thousand',
'million',
'billion',
'trillion',
'quadrillion'
]
# segMag = segment magnitude (starting at 1)
def convertTrio(number):
return ' '.join([words[int(number[0])], 'hundred', convertDuo(number[1:3])]) # convertDuo(number[1:3])
def convertDuo(number):
#if teens or less
if int(number[0]) == 1:
return words[int(number)]
#twenty-five
else:
return tens[int(number[0]) - 1] + '-' + words[int(number[1])]
if __name__ == "__main__":
string = []
numeralSegments = []
numeral = sys.argv[1]
if int(numeral) < 100:
print convertDuo(numeral)
else:
# split number into lists, grouped in threes
for i in range (0, len(numeral), 3):
numeralSegments.append(numeral[i:i+3])
numeralSegments.reverse()
# for every segment, convert to trio word and append thousand, million, etc depending on magnitude
for i in range (len(numeralSegments)):
string.append(convertTrio(numeralSegments[i]) + ' ' + placeholders[i])
# reverse the list of strings before concatenating to commas
string.reverse()
print ', '.join(string)
编辑
为了更具python风格,将其打包为一个整洁、可重用的模块。如果中的有两件事要做,这两件事应该分开
您的命令行解析(与sys.argv
有关的任何内容)是一回事。实际的“转换数字”功能完全是另一回事。您希望看起来更像这样
def segment( n ):
segList= []
while len(n) > 3:
segList.insert( 0, n[-3:] )
n= n[:-3]
segList.insert( 0, n )
return segList
然后,您的
number2string
函数就成为这个模块中一个易于重用的部分。请查看Perl模块的源代码。它很短,可以很容易地移植到Python(如果还没有这样做的话).使用模运算来分隔单元,而不是对数字进行切片。此函数将使用给定的数据结构转换小于100的数字
if __name__ == "__main__":
import sys
for number in sys.argv[1:]:
print number2string( number )
def转换(n):
q、 r=divmod(n,10)
如果q<2:
返回单词[n]
结果=tens[q-1]#偏移量,因为tens缺少第一个空值
如果r:
结果+='-'+字[r]
返回结果
然后使用convert递归地支持更大的数字,例如,从divmod(n,100)开始,等等。如果有人正在阅读此脚本,请查看 给予
呵呵,我把那张便条写在纸上,但还是弄错了(实际上,这不是家庭作业。这只是为了提高我的Python技能而做的一个练习。
string
是一个内置Python模块。使用与内置名称冲突的变量名称是一种不好的做法。您可以使用parts
代替。您是否尝试过用零填充数字(要使数字计数为三的倍数)?是的,也许填充是个好主意。另外,我目前正在将int转换为字符串来处理数字。在int类型中有没有办法做到这一点?数字?你的意思是(数字%10)?是的,有办法处理int的数字。(数字%10)是最右边的数字。谢谢。你对我写的代码的一般“python性”有什么评论吗。我是否应该用更实用的风格做一些事情?我已经习惯了非常严格的oop语言,如Java和C。谢谢number2string
提醒我str(number)
e.i.这个名字不能很好地传达函数的意图。在这种情况下,IMO perl的spell\u number
是一个更好的名字。@J.F.Sebastion:对不起,“spell\u number”对我来说是不透明的。命名是主观的,没有“更清晰”,只有“我喜欢的”。在教linux入门时,总有人反对“rm”删除一个文件。他们想拼写remove,“del”。不知道为什么。@S.Lott:我认为问题是“string”是非常通用的,并且不能告诉你字符串的形式——“42”和“42”一样是字符串表示法。但是拼写数字也有点不可解释-我会选择numberToWords()
def convert(n):
q, r = divmod(n, 10)
if q < 2:
return words[n]
result = tens[q-1] # offset because tens is missing first null value
if r:
result += '-' + words[r]
return result
import inflect
p = inflect.engine()
p.numwords(123456789)
'one hundred and twenty-three million, four hundred and fifty-six thousand, seven hundred and eighty-nine'