Я пытаюсь реализовать ленивое разбиение объекта итератора, которое дает срезы итератора, когда функция элемента итератора изменяет значения. Это имитировало бы поведение Clojure's partition-by (хотя семантика вывода была бы другой, поскольку 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([])