尝试在Python中实现延迟分区时感到愚蠢

时间:2011-04-29 18:10:21

标签: python iterator lazy-evaluation

我正在尝试实现迭代器对象的延迟分区,当迭代器的元素上的函数更改值时,该对象会生成迭代器的切片。这将模仿Clojure的分区行为(虽然输出的语义会有所不同,因为Python会真正“消耗”元素)。我的实现在它执行的操作数量上是最佳的,但在内存中并不是最佳的。我不明白为什么一个好的实现需要超过O(1)内存,但我的实现需要O(k)内存,其中k是分区的大小。我希望能够处理k很大的情况。有谁知道一个好的实现?

正确的行为应该是

>>>unagi = [-1, 3, 4, 7, -2, 1, -3, -5]
>>> parts = partitionby(lambda x: x < 0,unagi)
>>> print [[y for y in x] for x in parts]
[[-1], [3, 4, 7], [-2], [1], [-3, -5]]

这是我当前的版本

from itertools import *

def partitionby(f,iterable):
    seq = iter(iterable)
    current = next(seq)
    justseen = next(seq)
    partition = iter([current])
    while True:
        if f(current) == f(justseen): 
            partition = chain(partition,iter([justseen]))
            try:
                justseen = next(seq)
            except StopIteration:
                yield partition
                break
        else:
            yield partition
            current = justseen
            partition = iter([])

2 个答案:

答案 0 :(得分:3)

为什么不reuse groupby?我认为这是O(1)。

def partitionby(f, iterable):
    return (g[1] for g in groupby(iterable, f))

groupby与您的实现的区别在于partition是一个专门的迭代器对象,而不是chain chain chain {{1}} ...

答案 1 :(得分:0)

这让我觉得partition可能是一个正常的列表,而不是一个迭代器,即:。

partition = iter([current])
partition = chain(partition,iter([justseen]))
partition = iter([])

可能是:

partition = [current]
partition.append(justseen)
partition = []