lambda T:B("([+/*-])",lambda m:dict(zip("+/*-",S("z"," plus z divided by z times z minus ")))[m.group(0)],B("([+/*-]|^)-",r"\1negative ",B("[^+/*-]+","{}",T))).format(*[J([g[int(S("\.",j)[0])]+S("z",B("y","illion","z thousandz myz byz tryz quadry"))[len(S(",",m))+~i]+(" point "+J(s[int(c)]for c in S("\.",j)[-1]))*("."in j)for i,j in E(S(",",m))if 0<float(j)+(m<"1")])for m in S("[+/*-]+",T)[T[0]=='-':]])
from re import*
E,S,B,P=enumerate,split,sub," ";J=P.join
s,e=S(P,"zero one two three four five six seven eight nine"),[B("urty","rty",j)for i,j in E(c+d for d in S(P,"teen ty")for c in S(P,"twen thir four fif six seven eigh nine"))]
g=s+S(P,"ten eleven twelve")+e[1:8]+[a+(P+b)*(i>0)for a in e[8:]for i,b in E(s)]
g=[(j+" hundred ")*(i>0)+k for i,j in E(s)for k in g]
Hãy thử trực tuyến!
Rất nhiều thực hành xấu. Điều này gần như bị tổn thương để viết ....
Yêu cầu một chuỗi không unicode không có khoảng trắng làm đầu vào.
Giải trình:
# import all functions from re (python regex library)
from re import*
# rename some repeatedly-used functions/variables for reduced bytecount
E,S,B,P=enumerate,split,sub," ";J=P.join
# list the names of 0-9
s=S(P,"zero one two three four five six seven eight nine")
# generate "twenteen" through nineteen and twenty though ninety, changing "fourty" to forty
# using enumerate (E) even though i is not required b/c it's shorter than range(len(x))
# using re.split (S) instead of string.split since it's shorter
e=[B("urty","rty",j)for i,j in E(c+d for d in S(P,"teen ty")for c in S(P,"twen thir four fif six seven eigh nine"))]
# generate 0-999
# 0-9
g=s+
# 10, 11, 12
+S(P,"ten eleven twelve")+
# remove "twenteen", 13-19
+e[1:8]+
# tens' place + ones' place, if ones' place is not zero
+[a+(P+b)*(i>0) ]
# for each tens' place in 20-90
for a in e[8:]
# for each index, value in ones' places 0-9
for i,b in E(s)
# hundreds' place if at least 100, plus tens' and ones' place (already calculated and stored in g from before)
g=[(j+" hundred ")*(i>0)+k ]
# (s) stores names for 0-9, need index to avoid "zero hundred"
for i,j in E(s)
# for each hundred, iterate over all values (0-99) already in g
for k in g
# actual function to call. uses previously declared global variable g.
def f(T):
# gets the numbers in the supplied string (T) by splitting (T) on any operator character
# remove first item if blank (only happens when staring with a - for negative numbers)
n=S("[+/*-]+",T)[T[0]=='-':]
# triply-nested set of re.subs to convert (T) to a sting of where the operators are replaced by their names and numbers are replaced by "{}"
# EX: "-1-1--1" -> "-{}-{}--{}" -> "negative {}-{}-negative {}" -> "negative {} minus {} minus negative {}"
# this sub happens last
# re.sub (B) any operator, with the operators in a group "()" so that they return in match.group
T=B("([+/*-])", )
# an anonymous function to accept match objects (m) from re.sub's search.
,lambda m:
# create a dictionary from the combination of operators and their names
# like {"+":" plus ",...}
# operator names are surrounded by spaces since number names are NOT
dict(zip("+/*-",S("z"," plus z divided by z times z minus ")))
# from the constructed dictionary, select the operator matched by re.sub's search and return it for replacement
[m.group(0)],
# this substitution is second
# re.sub (B) any operator followed by a minus (-), OR a minus at the beginning of the string
# operators/start are grouped, trailing minus is not
,B("([+/*-]|^)-", )
# replace match with the grouped items plus the word "negative"
# EX: "-1-1--1" -> "-{}-{}--{}" -> "negative {}-{}-negative {}"
,r"\1negative ",
# this substitution is done first
# replace any sequence of NON-operators with "{}"
# this removes numbers so the names can be inserted later
# EX: "-1-1--1" -> "-{}-{}--{}"
,B("[^+/*-]+","{}",T))
# technically the previous construction of (T) and (n) can be placed here to save 5 bytes but my poor eyes can't handle that.
# insert constructed names back into original string.
# EX: "-1-1--1" -> "negative {} minus {} minus negative {}" -> "negative one minus one minus negative one"
print T.format( )
# string.format needs items in array unpacked, or it will attempt to insert the string representation of the array itself
*[ ]
# for each number pulled from (T), generate names and join generated items back together with spaces
# EX: "1,456" -> ["1", "456"] -> ["one thousand", "four hundred fifty six"] -> "one thousand four hundred fifty six"
J( )for m in n
# split j on periods (.) and take the first item
# convert that item into an integer and find the item at that index in g (0-999)
[g[int(S("\.",j)[0])]+ ]
# insert prefix for millions +, split string on "z" (spaces must be preserved for proper separation)
+S("z",B("y","illion","z thousandz myz byz tryz quadry"))
# left is largest, so take the item at index (total # of groups - current place - 1)
[len(S(",",m))+~i]+
# if group had a period, split string on period and take last item
# replace every character in group with number 0-9 name
# join them with spaces and add back to rest of group
+(" point "+J(s[int(c)]for c in S("\.",j)[-1]))*("."in j)
# split number into groups by comma
# EX: "123,456" -> ["123","456"]
# only return item if j != 0 (avoids returning empty string which will result in too many joined spaces)
# OR if m == 0 (avoids not returning anything when should return "zero")
for i,j in E(S(",",m))if 0
Tôi giảm khoảng 150 byte trong khi viết lời giải thích. Hãy để nó không bao giờ được nói rằng bình luận / xem xét mã của bạn là không hữu ích!
123,456,789,012,345.6789
vào các ví dụ? Nó sẽ bao gồm rất nhiều trường hợp thử nghiệm.