Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sequence of function iterations

Is there a way to abuse assignment expressions or functional tools to generate the sequence x, f(x), f(f(x)), ... in one line?

Here are some contrived examples to demonstrate:

def iter(x, f, lim=10):
    for _ in range(lim):
        yield x
        x = f(x)

iter(1, lambda x: (2*x)%99)

(This makes one extra function call that goes unused. Ideally this is avoided.)

Another weird idea I had is "One-argument accumulate", even uglier. The idea is to use the binary function but ignore the list elements! It's not a good use of accumulate.

from itertools import accumulate
list(accumulate([None]*10, lambda x,y:2*x, initial=1))
like image 449
qwr Avatar asked Aug 10 '26 23:08

qwr


2 Answers

You can use a counter in a list comprehension to determine whether to initialize a number with an assignment expression or to aggregate it with your desired function (assumed to be f = lambda x: (2 * x) % 99 here):

[n := f(n) if i else 1 for i in range(10)]

This returns:

[1, 2, 4, 8, 16, 32, 64, 29, 58, 17]

Demo: https://ideone.com/Ye25ek

like image 132
blhsing Avatar answered Aug 12 '26 11:08

blhsing


f = lambda x: (2 * x) % 99
[x := 1, *((x := f(x)) for _ in range(9))]
  1. x := 1: This initializes x to 1 and places it as the first element in the lis

  2. *((x := f(x)) for _ in range(9)):

    • Creates a generator expression that runs 9 times

    • Each time it applies the function f to the current value of x

    • Assigns the result back to x using the walrus operator (:=)

    • Returns each new value of x

    • The * unpacks all these values into the list

like image 39
Bhargav Avatar answered Aug 12 '26 13:08

Bhargav



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!