How Can I Create The Fibonacci Series Using A List Comprehension?
Solution 1:
You cannot do it like that: the list comprehension is evaluated first, and then that list is added to series
. So basically it would be like you would have written:
series=[]
series.append(1)
series.append(1)
temp = [series[k-1]+series[k-2] for k in range(2,5)]
series += temp
You can however solve this by using list comprehension as a way to force side effects, like for instance:
series=[]
series.append(1)
series.append(1)
[series.append(series[k-1]+series[k-2]) for k in range(2,5)]
Note that we here do not add the result to series. The list comprehension is only used such that .append
is called on series
. However some consider list comprehensions with side effects rather error prone: it is not very declarative and tends to introduce bugs if not done carefully.
Solution 2:
We could write it as a clean Python list comprehension (or generator) using it's relationship to the golden ratio:
>>>series = [int((((1 + 5**0.5) / 2)**n - ((1 - 5**0.5) / 2)**n) / 5**0.5) for n inrange(1, 21)]>>>series
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765]
>>>
or a little more nicely as:
>>>square_root_of_five = 5**0.5>>>Phi = (1 + square_root_of_five) / 2>>>phi = (1 - square_root_of_five) / 2>>>>>>series = [int((Phi**n - phi**n) / square_root_of_five) for n inrange(1, 21)]>>>series
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765]
Solution 3:
If you know how many terms of the series you will need then you can write the code compactly without a list comprehension like this.
defFibonacci(n):
f0, f1 = 1, 1for _ inrange(n):
yield f0
f0, f1 = f1, f0+f1
fibs = list(Fibonacci(10))
print (fibs)
If you want some indefinite number of terms then you could use this, which is very similar.
def Fibonacci():
f0, f1 = 1, 1while True:
yield f0
f0, f1 = f1, f0+f1
fibs = []
for f inFibonacci():
fibs.append(f)
if f>100:
breakprint (fibs)
When you need a potentially infinite collection of items you should perhaps consider either a function
with one or more yield
statements or a generator expression. I'd love to be able to make Fibonacci numbers with a generator expression but apparently one can't.
Solution 4:
Using Assignment Expression (python >= 3.8):
s = [0, 1]
s += [(s := [s[1], s[0] + s[1]]) and s[1] for k in range(10)]
print (s)
# [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
Solution 5:
To build on what Willem van Onsem said:
The conventional way to calculate the nth term of the fibonacci sequence is to sum the n-1
and n-2
terms, as you're aware. A list comprehension is designed to create a list with no side effects during the comprehension (apart from the creation of the single list). Storing the last 2 terms of the sequence during calculation of the sequence is a side-effect, therefore a list comprehension is ill-suited to the task on its own.
A safe way around this would be to make a closure generator (essentially a generator with some associated private state) that can be passed to the list comprehension such that the list comprehension does not have to worry about the details of what's being stored:
deffib_generator(n):
deffib_n_generator():
last = 1
curr = 1if n == 0:
returnyield last
if n == 1:
returnyield curr
if n == 2:
return
ii = 2while ii < n:
next = curr + last
yieldnext
last = curr
curr = next
ii += 1return fib_n_generator()
fib = [xx for xx in fib_generator(10)]
print(fib)
Post a Comment for "How Can I Create The Fibonacci Series Using A List Comprehension?"