Mapping lists in Python with mutable state between iterations

I have something that looks a lot like comprehension of lists in Python, except that it shares a variable state between iterations. Is there a way to do this with a list comprehension?

def f(x):
    """ 5-bit LFSR """
    return (x >> 1) ^ (0x12*(x&1))

def batch(f, x, n):
    result = [x]
    for _ in xrange(1,n):
        x = f(x)
        result.append(x)
    return result

batch(f, 1, 5)

which returns [1, 18, 9, 22, 11]. The function is important here batch, and not f(x), which is just a simple example here to illustrate the problem.

Alternatively, I could implement using a generator:

def batch(f, x, n):
    yield x
    for _ in xrange(1,n):
        x = f(x)
        yield x

list(batch(f, 1, 5))

But it smells a bit uncomfortable. I'm looking for something like this ...

batch = [??? for _ in xrange(n)]
+4
source share
3 answers

. . itertools.accumulate, , 2.7. " " Python docs, .

+4

?

, , - ...

batch = [??? for _ in xrange(n)]

, :

>>> x = 1
>>> n = 5
>>> [prev.append(f(prev[0])) or prev.pop(0) for prev in [[x]] for _ in xrange(n)]
[1, 18, 9, 22, 11]

. . ( , user2357112 , )

+10

, , , reduce ( functools.reduce Python 3):

>>> f = lambda x: (x >> 1) ^ (0x12*(x&1))
>>> x, n = 1, 5
>>> functools.reduce(lambda lst, _: lst + [f(lst[-1])], range(1, n), [x])
[1, 18, 9, 22, 11]

, , . , :

>>> functools.reduce(lambda lst, _: lst.append(f(lst[-1])) or lst, range(1, n), [x])
[1, 18, 9, 22, 11]

Or, as I already hinted in another answer, you can use itertools.accumulatethat much better, but still a little misuse, since it actually expects a binary function, whereas here we do not use either the second parameter or the actual iterable passed to the function, except for the very first value.

>>> list(itertools.accumulate([x] * n, lambda y, _: f(y)))
[1, 18, 9, 22, 11]
+3
source

Source: https://habr.com/ru/post/1690744/


All Articles