The bottom line is to get a function that retains its value and the values ​​of the variables in its area. She accepts them and adds them to the list, then, if necessary, all the accumulated data is returned. I wanted to implement using the generator, but failed:

def acc(item=0,stop=0): buffer = [] while item !=stop: buffer.append(item) yield "+" return buffer 

    2 answers 2

    Using a generator function is a bit different than using a regular function. For the basics, see Chapter 20 of the Learning Python tutorial by Mark Lutz. For enlightenment to David Beazley's presentations - " Generator Tricks for Systems Programmers ", " A Curious Course on Coroutines and Concurrency " and " Generators: The Final Frontier ". First example:

     def acc(): buf = [] while True: # Получаем отправленные в генератор значения value, command = yield buf.append(value) if command: break yield buf # Получаем генератор g = acc() # Инициализируем генератор next(g) # Отправляем в генератор значения g.send((1, False)) g.send((2, False)) g.send((3, False)) # Получаем накопленные значения из генератора items = g.send((4, True)) 

    We will get rid of the initialization step using the decorator, and at the same time from having to send tuples to the generator:

     def coroutine(func): def init(*args, **kwargs): cr = func(*args, **kwargs) next(cr) return cr return init @coroutine def acc(): buf = [] while True: value = yield if value is StopIteration: break buf.append(value) yield buf g = acc() g.send(1) g.send(2) g.send(3) items = g.send(StopIteration) 

    Now let's try to eliminate the need to call send :

     def coroutine(func): def init(*args, **kwargs): cr = func(*args, **kwargs) next(cr) return lambda x: cr.send(x) return init @coroutine def acc(): ... g = acc() g(1) g(2) g(3) items = g(StopIteration) 

    The same effect can be achieved with the help of a closure :

     def acc(): buf = [] def f(item): if item is None: return buf buf.append(item) return f a = acc() a(1) a(2) a(3) items = a(None) 

    Or using the function attributes (for educational purposes only!):

     def acc(item): if not hasattr(acc, '_buf'): acc._buf = [] if item is None: items, acc._buf = acc._buf, [] return items acc._buf.append(item) acc(1) acc(2) acc(3) items = acc(None) 
    • Thank you for the detailed response and a comprehensive answer) - Valvea

    Necessarily - as a function?

    In the form of a class, this is done elementarily. Class:

     class Accum(): def __init__(self): self.list = [] def put(self, atom): self.list.append(atom) get (self): return(self.list) 

    Use class:

     x = Accum() x.put(2) x.put(10) x.put(7) print(x.get()) 

    Not tested, so there may be errors. But the idea, I think, is clear.