Массив чисел фибоначчи питон

Fibonacci sequence using list in PYTHON?

I have a problem about making a fibonacci sequence to a list, I’m just new to python someone help me please. This is my code. I know this is looking wrong or something because it says invalid syntax. I don’t know what to do about this really 🙁 This code works for a normal code without using a list!

myArray1 = [0] myArray2 = [1] while myArray2 < 700: myArray1, myArray2 = b[i], myArray1+myArray2[i] print(myArray2) 

Also, you're trying to compare a list to an integer ( while myArray2 < 700 ). That won't raise an error (which is a shame), but I'm fairly certain that's not what you want to do.

7 Answers 7

This code puts the first 700 fibonacci numbers in a list. Using meaningful variable names helps improve readability!

fibonacci_numbers = [0, 1] for i in range(2,700): fibonacci_numbers.append(fibonacci_numbers[i-1]+fibonacci_numbers[i-2]) 
In [77]: a = 0 . b = 1 . while b < 700: . a, b = b, a+b . print a, b 1 1 1 2 2 3 3 5 5 8 8 13 13 21 21 34 34 55 55 89 89 144 144 233 233 377 377 610 610 987 

If you wanna store the results in a list, use list.append :

In [81]: a = 0 . b = 1 . fibo=[a, b] . while b < 70: . a, b = b, a+b . fibo.append(b) . print fibo [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89] 

There are two kinds of mistakes you are making; mistakes that are creating errors and mistakes that are affecting readability

Both instances of the phrase [i] should be removed. I believe that you may be thinking it has something to do with iteration or tuples, but that is part of the reason you are getting errors:

myArray1 = [0] myArray2 = [1] while myArray2 < 700: myArray1, myArray2 = b, myArray1+myArray2 print(myArray2) 

the other part of the reason you are getting errors is because of the variable b. You don't declare it and it does not belong. This code will iterate correctly if you switch out b with myArray2:

myArray1 = [0] myArray2 = [1] while myArray2 < 700: myArray1, myArray2 = myArray2, myArray1+myArray2 print(myArray2) 

then there are some legibility issues. I would change the phrase myArray1 and 2 to a and b respectively. First because it is just too long; second because in python it is called lists, not arrays; third because you are referring to integers, not lists or arrays:

Читайте также:  Уведомление php yii base errorexception

then, the variables that were myArray1 and 2, but are now a and b; those are integers and they do not need to be expressed as single object lists. so get rid of the brackets around them:

Then, the last phrase in this code says print(b). If you have it printing b then the fibonacci sequence you get is missing its first 1. It will read (on separate lines of course) 1,2,3,5,8,13 and so on. It should read 1,1,2,3,5,8,13. You are missing the first 1. So print(b) needs to be changed to print(a):

then, if you are expressing more than one variable you can just list all the variables separated by commas equal to all the values separated by commas like this:

so for your code that would translate to:

then get rid of that extra space, white space means something in python, though here it doesn't really make a difference:

So all of this so far has just been enough to get you to your original problem: you are getting an iteration (each consecutive value on a seperate line). Below is how you can get a list to any number n:

def fibo(n): fibo_list = [] a,b = 0,1 while b < n: a,b = b,a+b fibo_list.append(a) print(fibo_list) 

Источник

How can I create the fibonacci series using a list comprehension?

I am new to python, and I was wondering if I could generate the fibonacci series using python's list comprehension feature. I don't know how list comprehensions are implemented. I tried the following (the intention was to generate the first five fibonacci numbers):

series=[] series.append(1) series.append(1) series += [series[k-1]+series[k-2] for k in range(2,5)] 

This piece of code throws the error: IndexError: list index out of range . Let me know if it is even possible to generate such a series using a list comprehension.

You cannot do it like that since the list comprehension is evaluated fist before it is added to the series .

reduce is a better choice for fibonacci series as the input of iteration X depends on the output of iteration X -1

13 Answers 13

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.

Using assignment expressions in python3.8, you can bypass the list comprehension with side effects to create a new list of fib numbers. Whether it's better than using side effects (as you've done here) is debatable.

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 in range(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 in range(1, 21)] >>> series [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765] 

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.

def Fibonacci(n): f0, f1 = 1, 1 for _ in range(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, 1 while True: yield f0 f0, f1 = f1, f0+f1 fibs = [] for f in Fibonacci(): fibs.append(f) if f>100: break print (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.

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] 

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:

def fib_generator(n): def fib_n_generator(): last = 1 curr = 1 if n == 0: return yield last if n == 1: return yield curr if n == 2: return ii = 2 while ii < n: next = curr + last yield next last = curr curr = next ii += 1 return fib_n_generator() fib = [xx for xx in fib_generator(10)] print(fib) 

Thanks for the explanation in the first para that states 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 .

However, even after spending 15+ mins I cannot understand what's the benefit of using yield in above code snippet. fib = [xx for xx in fib_generator(10)] would have still be called if fib_generator(n) be a function w/o generator.

The yield is crucial, else it's not a generator. Without the yield fib_n_generator() would just return one thing, not an iterable of things. I could have made my answer simpler though: I didn't need to nest the function, so it should have looked like Bill Bell's answer (which is why his has more upvotes 😉 ). I could also have re-written it to return a list instead of a generator, but that would defeat the main purpose of using a generator, which is to avoid unnecessary RAM usage.

Источник

It's okay (and encouraged) to ask and answer your own on-topic questions. This is a bad question, any way you slice it. This site is about solving programming problems, not a competition to see who can produce a "one liner".

@roppi ..See the link of the question I provided in the text.. it was also similar but it did help other people..

6 Answers 6

I have the following working solutions:

A. Using lambda() + reduce():

 >>> fib = lambda n: reduce(lambda x, _: x+[x[-1]+x[-2]], range(n-2), [0, 1]) >>> fib(10) >>> [0, 1, 1, 2, 3, 5, 8, 13, 21, 34] 

Note: Not able to use x.append(x[-1]+x[-2]). Gives AttributeError (Don't know why)

B. Using lambda() + map(): (Have to use a variable for result)

 >>> result = [0,1] >>> fib = lambda n: map(lambda _: result.append(result[-1] + result[-2]), xrange(n-2)) >>> fib(10) ## Ignore its output ## >>> result ## Stores the result ## >> [0, 1, 1, 2, 3, 5, 8, 13, 21, 34] 

I see two problems with your lambda() + reduce() solution. The first is you avoid doing a reduction by ignoring the second lambda() argument and treat reduce() as a simple iterator . The second problem is that fib(1) and fib(2) produce the same result but they shouldn't.

about your note, that is because x.append(. ) return None because is a operation in place of list, while reduce expect your the function to return a value that is going to be used in the next iteration, for that you can do this (x.append(. ),x)[1]

I see two problems with your lambda() + map() solution. The first is that it doesn't work in Python 3 as its extreme lazy evaluation doesn't fill out result until something consumes the result of map() . (E.g. try wrapping your map() in an any() ) The second problem is that fib(1) and fib(2) produce the same result but they shouldn't.

@Copperfield fib = lambda n: reduce(lambda x, _: x+[x[-1]+x[-2]], range(n-1), [0, 1])[:-1] also works.

Fibonacci using reduce() and lambda()

from functools import reduce def fibonacci(count): sequence = (0, 1) for _ in range(2, count): sequence += (reduce(lambda a, b: a + b, sequence[-2:]), ) return sequence[:count] print(fibonacci(10)) 

Fibonacci using map() and lambda()

def fibonacci(count): sequence = [0, 1] any(map(lambda _: sequence.append(sum(sequence[-2:])), range(2, count))) return sequence[:count] print(fibonacci(10)) 

Code Snippet:

fibonacci = lambda number: number if number  
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181] 

In place of 20, you can give your number. I hope this helps:)

yo can try this for Fibonacci using reduce() and lambda()

def Fib(count): first =[0,1] for i in range(0,count-2): first.append(reduce(lambda x,y : x+y,first[-2:])) print(first) Fib(10) 

output

Here's what might help you! Implemented using reduce() and lambda

from functools import reduce fibonacci_seq = [0, 1] n = 10 reduce(lambda a, b: len(fibonacci_seq) < n and (fibonacci_seq.append(a+b) or a+b), fibonacci_seq) 

(fibonacci_seq.append(a+b) or a+b) : as the .append(ele) returns None , I'm using it to append the next element in the series to the fibonacci_seq . or ing it with a+b allows to return a+b as the result to the reduce() function to operate on it with the next element in the sequence.

print(fibonacci_seq) >>> [0, 1, 1, 2, 3, 5, 8, 13, 21, 34] 

The above method returns the right sequence for n = 2 onwards.

Источник

Оцените статью