Le 10/04/2018 à 00:54, Peter O'Connor a écrit : > Kyle, you sounded so reasonable when you were trashing > itertools.accumulate (which I now agree is horrible). But then you go > and support Serhiy's madness: "smooth_signal = [average for average in > [0] for x in signal for average in [(1-decay)*average + decay*x]]" which > I agree is clever, but reads more like a riddle than readable code. > > Anyway, I continue to stand by: > > (y:= f(y, x) for x in iter_x from y=initial_y) > > And, if that's not offensive enough, to its extension: > > (z, y := f(z, x) -> y for x in iter_x from z=initial_z) > > Which carries state "z" forward but only yields "y" at each iteration. > (see proposal: https://github.com/petered/peps/blob/master/pep-9999.rst > <https://github.com/petered/peps/blob/master/pep-9999.rst>) > > Why am I so obsessed? Because it will allow you to conveniently replace > classes with more clean, concise, functional code. People who thought > they never needed such a construct may suddenly start finding it > indispensable once they get used to it. > > How many times have you written something of the form?: > > class StatefulThing(object): > > def __init__(self, initial_state, param_1, param_2): > self._param_1= param_1 > self._param_2 = param_2 > self._state = initial_state > > def update_and_get_output(self, new_observation): # (or just > __call__) > self._state = do_some_state_update(self._state, > new_observation, self._param_1) > output = transform_state_to_output(self._state, self._param_2) > return output > > processor = StatefulThing(initial_state = initial_state, param_1 = > 1, param_2 = 4) > processed_things = [processor.update_and_get_output(x) for x in x_gen] > > I've done this many times. Video encoding, robot controllers, neural > networks, any iterative machine learning algorithm, and probably lots of > things I don't know about - they all tend to have this general form. >
Personally I never have to do that very often. But let's say for the sake of the argument there is a class of problem a part of the Python community often solves with this pattern. After all, Python is a versatile language with a very large and diverse user base. First, why a class would be a bad thing ? It's clear, easy to understand, debug and extend. Besides, do_some_state_update and transform_state_to_output may very well be methods. Second, if you really don't want a class, use a coroutine, that's exactly what they are for: def stateful_thing(state, param_1, param_2, output=None): while True: new_observation = yield output state = do_some_state_update(state, new_observation, param_1) output = transform_state_to_output(state, param_2) processor = stateful_thing(1, 1, 4) next(processor) processed_things = [processor.send(x) for x in x_gen] If you have that much of a complex workflow, you really should not make that a one-liner. And before trying to ask for a new syntax in the language, try to solve the problem with the existing tools. I know, I get the frustration. I've been trying to get slicing on generators and inline try/except on this mailing list for years and I've been said no again and again. It's hard. But it's also why Python stayed sane for decades. _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/