Discuss / Python / 第三题

第三题

Topic source
def fnfloat(x,y):
    return x*0.1+y
def char2num(s):
    return {'0':0,'1':1,'2':2,'3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s]
def str2float(s):
    ss = s.split('.')
    num1 = reduce(lambda x,y:x*10+y,map(char2num,ss[0]))
    num2 = reduce(fnfloat,map(char2num,ss[1][::-1]))*0.1
    return num1 + num2

首先将字符串123.456用split分为123和456,然后123用reduce生成num1,456字符串反转 一下生成654,然后调用fnfloat生成4.56,最后再乘0.1,成为0.456,即num2,最后相加。

这才是正解

我想到的办法也是这个,只是有个小小的疑问想不通: 浮点部分的如果用 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这种格式化/占位符方式(显然不是一个普适的好办法)还有什么别的好办法吗?

laputa6616

#5 Created at ... [Delete] [Delete and Lock User]

非要将「乘以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

Reply