使用python map将列表中所有浮点数替换为四舍五入的字符串类型浮点数

1 投票
3 回答
4046 浏览
提问于 2025-04-16 23:29

我有一个函数,它接收一个浮点数的列表,然后返回这个列表,但每个数字的小数点后面都保留四位,结果以字符串的形式呈现。

现在这个函数的写法很简单,如下所示:

for i in range(len(floats)):
   floats[i] = "%.4f" %floats[i]

这个函数能完成这个任务。

但是我想知道,能不能用 map 函数来实现这个功能?因为有个网站说使用 map 会更快。

我这个函数要调用几千次,从性能分析的结果来看,它是耗时比较多的函数之一。

3 个回答

0

如果你想使用 map 函数,可以参考下面的示例:

map(lambda x: "%.4f" % x, [random() for i in xrange(10)])

不过 @Felix 说得对,使用列表推导会更快:

["%.4f" % x for x in [random() for i in xrange(10)]]

另外,这个方法不是很清楚,如果你的列表中不仅包含浮点数,而且你想保留其他类型的数据,可以这样做:

["%.4f" % x if isinstance(x, float) else x for x in listValues]

或者如果你只想保留字符串形式的浮点数,可以这样:

["%.4f" % x for x in listValues if isinstance(x, float)]
2

好的,先说说基本情况:

python -m timeit 
    "from random import randint; 
     floats = [randint(0, 1000000)/1000.0 for unused in range(10000)]" 
    "for i in range(len(floats)): 
     floats[i] = '%.4f' % floats[i]"
10 loops, best of 3: 48.7 msec per loop

有趣的是,新的字符串格式化方式反而稍微慢了一点。用 '{0:5.4f}'.format(floats[i]) 这种写法,每次循环大约需要54毫秒。当用 xrange 代替 range 时也是这样。

接下来,很多人建议的一个改进方法是使用列表推导式:

python -m timeit 
    "from random import randint; 
     floats = [randint(0, 1000000)/1000.0 for unused in range(10000)]" 
    "floats = ['%.4f' % f for f in floats]"
10 loops, best of 3: 48.1 msec per loop

让我感到惊讶的是(至少对我来说),这个方法并没有明显快很多!不过,@Felix King 已经提到过,列表推导式只有在使用内置函数时才会更快。

我真的没有其他想法来让这个过程更快,所以我建议,如果你对内存使用没有问题的话,可以使用列表推导式,因为它更易读,也更符合 Python 的风格。

4

map 只有在你使用内置函数的时候才会更快(或者至少我之前读到的时候是这样 ;))。不过你也可以使用列表推导式:

pattern = "%.4f"
floats = [pattern % i for i in floats]

要注意的是,map 和列表推导式会创建一个新的列表,而 for 循环则不会。这一点可能很重要。

根据你应用的其他部分,如果可能的话,你应该在把数字添加到列表的时候就格式化这些数字。

撰写回答