Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

List comprehensions in Python with mutable state between iterations

I have something which is an awful lot like a list comprehension in Python, except that it shares mutable state between iterations. Is there any way to do it 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]. Here the important thing is the batch function, not f(x) which is here just a simple example to illustrate the issue.

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 little awkward. What I'm looking for is something like this...

batch = [??? for _ in xrange(n)]
like image 901
Jason S Avatar asked Dec 13 '17 22:12

Jason S


2 Answers

Is there any way to do it with a list comprehension?

What I'm looking for is something like this...

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

Sure, no problem:

>>> 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]

Note: This is a bad idea. (I pretty much only did this because user2357112 said there is no way)

like image 160
Stefan Pochmann Avatar answered Sep 28 '22 06:09

Stefan Pochmann


No. Deliberately no. Eventually they put in itertools.accumulate, which is the closest thing to an Officially Recommended way to implement recurrence relations in a functional manner, but it doesn't exist on 2.7. You could copy the "roughly equivalent to" Python implementation from the docs if you want.

like image 28
user2357112 supports Monica Avatar answered Sep 28 '22 06:09

user2357112 supports Monica