![](/img/trans.png)
[英]Is there a more efficient way to call functions with different arguments multiple times?
[英]Efficient way to call multiple reduce functions on an iterable in Python?
我想在 Python (2.7) 中的可迭代对象上运行几个 reduce 函数。 一个例子是对整数的可迭代调用min
和max
。 但是当然你不能在同一个迭代器上调用reduce(min, it)
和reduce(max, it)
,因为它在第一次调用后就耗尽了。 因此,您可能会考虑执行以下操作:
reduce(lambda a, b: (min(a[0], b[0]), max(a[1], b[1])), ((x, x) for x in it))
你认为,嘿,这很漂亮,所以你把它概括为这样的:
from itertools import izip
def multireduce(iterable, *funcs):
""":Return: The tuple resulting from calling ``reduce(func, iterable)`` for each `func` in `funcs`."""
return reduce(lambda a, b: tuple(func(aa, bb) for func, aa, bb in izip(funcs, a, b)), ((item,) * len(funcs) for item in iterable))
(你喜欢单元测试,所以你包括这样的东西:)
import unittest
class TestMultireduce(unittest.TestCase):
def test_multireduce(self):
vecs = (
((1,), (min,), (1,)),
(xrange(10), (min, max), (0, 9)),
(xrange(101), (min, max, lambda x, y: x + y,), (0, 100, (100 * 101) // 2))
)
for iterable, funcs, expected in vecs:
self.assertSequenceEqual(tuple(multireduce(iterable, *funcs)), expected)
但是当你尝试它时,你会发现它真的很慢:
%timeit reduce(min, xrange(1000000)) ; reduce(max, xrange(1000000))
10 loops, best of 3: 140 ms per loop
%timeit reduce(lambda a, b: (min(a[0], b[0]), max(a[1], b[1])), ((x, x) for x in xrange(1000000)))
1 loop, best of 3: 682 ms per loop
%timeit multireduce(xrange(1000000), min, max)
1 loop, best of 3: 1.99 s per loop
哎哟。 那么你来到 Stack Overflow 寻找 Python 优化智慧......
嗯,就是这样,这有点违背了迭代的意义......
def multireduce(iterable, *funcs):
""":Return: The tuple resulting from calling ``reduce(func, iterable)`` for each `func` in `funcs`."""
return tuple(imap(reduce, funcs, tee(iterable, len(funcs))))
但是对于我的测试用例来说速度非常快:
%timeit multireduce(xrange(1000000), min, max)
10 loops, best of 3: 166 ms per loop
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.