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))
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
f = lambda x: (2 * x) % 99
[x := 1, *((x := f(x)) for _ in range(9))]
x := 1: This initializes x to 1 and places it as the first element in the lis
*((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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With