簡體   English   中英

在Python中的可迭代對象上調用多個reduce函數的有效方法?

[英]Efficient way to call multiple reduce functions on an iterable in Python?

我想在 Python (2.7) 中的可迭代對象上運行幾個 reduce 函數。 一個例子是對整數的可迭代調用minmax 但是當然你不能在同一個迭代器上調用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM