Моя актуальная проблема гораздо больше, но суть его есть что-то вроде:Itertools/функциональный подход к обработке состояния над объектом?
def rec_func(it, newit, idx=0, seen_5=False, even_seen=0):
num = next(it, None)
if num is None:
return newit
elif num == 5: seen_5 = True
elif num&1==0: even_seen +=1
else: num*=20
newit.append(num)
print '[{}] seen_5 = {}, even_seen = {}'.format(idx, seen_5, even_seen)
return rec_func(it, newit, idx+1, seen_5, even_seen)
Выполнить с (http://ideone.com/4kBbhn):
a = []
rec_func(iter(xrange(10)), a)
print 'a =', a
Но есть некоторые серьезные проблемы с этим дизайном, рекурсия ISN что эффективный в Python и список создается и передается только для его результата (который не является генератором). Попытка получить это:
a = tuple(itertools.<something>(func, iter(xrange(10)))
print a # same answer as before
Как делать я? - Все, что я могу думать:
def func(num, state):
if num == 5: state['seen_5'] = True
elif num&1==0: state['even_seen'] +=1
else: num*=20
print '[?] seen_5 = {}, even_seen = {}'.format(state['seen_5'],
state['even_seen'])
return num
_state = {'seen_5': False, 'even_seen': 0}
print tuple(imap(partial(func, state=_state), xrange(10)))
Который работает, но, кажется, вид ужасный ... есть функциональное решение?
Если вы хотите сохранить состояние, то почему бы не написать класс, создать экземпляр, а затем сопоставить метод над iterable? Затем метод может хранить любое состояние, которое ему нужно для экземпляра. Попытка сделать это просто с функцией кажется бесполезно ограничительной. – BrenBarn
@BrenBarn Должна быть причина, так как OP помечен как «чисто функциональный». –
Я отредактировал пример, проходящий в объекте, который хранит свою собственную память (поэтому передает по ссылке в Python). Это уродливо, и я предпочел бы функциональное решение, вы знаете об этом? - Может быть, использовать аккумуляторы? –