使用python map将列表中所有浮点数替换为四舍五入的字符串类型浮点数
我有一个函数,它接收一个浮点数的列表,然后返回这个列表,但每个数字的小数点后面都保留四位,结果以字符串的形式呈现。
现在这个函数的写法很简单,如下所示:
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
循环则不会。这一点可能很重要。
根据你应用的其他部分,如果可能的话,你应该在把数字添加到列表的时候就格式化这些数字。