第三题
Topic source我想到的办法也是这个,只是有个小小的疑问想不通: 浮点部分的如果用 lambda的话,我写的是:
reversedstrafter_dot = map(char2num,list(s[s.index('.')+1:]).__reversed())
float_part = reduce(lambda x,y:x0.1+y,reversed_str_after_dot)0.1
如何修改一下才能让lambda一下生成目标浮点值0.456而不是先生成4.56再除以10呢?
式中的lambda的最后一步是相加而不是相除,和这个有关吗?
如果改为lambda x,y : 0.1(x0.1+y),值就不对了,为什么呢?
回复以后的乘号*不见了 重新写一下
#coding=utf-8
from functools import reduce
'''
利用map和reduce编写一个str2float函数,把字符串'123.456'转换成浮点数123.456:
'''
def str2float(s):
def char2num(c):
return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[c]
int_parts_str = map(char2num,s[:s.index('.')])
float_parts_str_reversed = map(char2num,list(s[s.index('.')+1:]).__reversed__())
int_sum = reduce(lambda x,y:x*10+y,int_parts_str)
float_sum = 0.1*reduce(lambda x,y:x*0.1+y,float_parts_str_reversed)
return int_sum + float_sum
print(str2float('123.456'))
Q1:怎样将乘以0.1这一操作移到lambda内呢? Q2:小数点位多了怎么办?除了用%.100f这种格式化/占位符方式(显然不是一个普适的好办法)还有什么别的好办法吗?
非要将「乘以0.1」移到 lambda 内部,可以这样操作:
float_sum = reduce(lambda x, y: (x + y)*0.1, mape(char2num, '0' + s[s.index('.')+1:][::-1])
即将小数部分'456'末尾加'0',再倒叙成'0654',然后 lambda:(x + y)*0.1 作用就可以了。
原来如此,好巧妙。我说怎么搞也算不对,总觉得哪儿少了什么好像,原来是末位的0,是不是相当于针对lambda中的x初始赋值为0呢? 总之太赞了! 那么代码其实也可以在其它不变的情况下,为reduce加上第三个参数,initial=0,即:
float_sum = reduce(lambda x, y: (x + y)*0.1, float_parts_str_reversed,0)
此外,作为一段相对严谨的代码,如果输入的值是'123.4567890',即末尾是0的小数时,怎样显示那个末尾的0呢? (类似
print(Decimal('123.4567890'))
的效果,甚至是类似
print(Decimal('0.0000000000000000))
的样子(小数部分位数超过6位,使用%f后面不显示 ,使用%.100f后面会显示错误(浮点)) %.100f中间的100可以用变量代替吗?比如:
s = '123.4567890'
k=len(s)-s.index('.')-1 #不含小数点的长度
print('%(k)f'%'str2float(s))
可是这代码是无法运行的……有什么方法解决,实现变化的精度控制?
- 1
这个名字足够长
首先将字符串123.456用split分为123和456,然后123用reduce生成num1,456字符串反转 一下生成654,然后调用fnfloat生成4.56,最后再乘0.1,成为0.456,即num2,最后相加。