Let's say I have a list where each element depends on the two previous elements eg. Fibonacci:
fibonacci = [0,1,1,2,3,5,8,13,21]
I want to create such a list using a comprehension like so:
fibonacci = [0,1] + [previous_element+element_before_previous_element for _ in range(7)]
(7 here is just some arbitary value for how long the list should be excluding the starting 2 values.)
How do I access previous_element
and element_before_previous_element
, and use 0 and 1 as starting values?
Note: I know this is trivial with a for loop but I need to able to write this in one line.
[j := 0, k := 1] + [(k := j + (j := k)) for i in range(7)]
For future readers:
What's this? :=
it's walrus operator that was introduced in Python 3.8 for new assignment everywhere in your code just like here. https://realpython.com/python-walrus-operator/
For start, I assign 0 and 1 to j and k respectively, and we do 2 task same time. create a list: [0, 1]
and assign j and k values.
it's equivalent to:
j, k = 0, 1
lst = [j, k]
now, second part: assume this without any walrus operator:
[(j + (k)) for i in range(7)]
It means a list of j + k
for 7 times. But If you need Fibonacci, you must update j and k every times... update k to j (previous) value and assign new value to k...
step | j | k |
---|---|---|
1 | 0 | 1 |
2 | 1 | 2 |
3 | 2 | 3 |
see? this mean if you get new value, assign it to k and assign current value of k to j, but do second task first
[(k := j + (j := k)) for i in range(7)]
this snippet does that. it gets j
(current value) j +
and assigns k
current value to j
then assigns j + k
to k
.
all done!
output:
[0, 1, 1, 2, 3, 5, 8, 13, 21]