Python Forum
My code which adds fibonacci numbers to a list adds too many terms.
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
My code which adds fibonacci numbers to a list adds too many terms.
#1
Hi, I am new to programming and am self-learning, using projecteuler as a source of questions. I am trying to create a program which generates the fibonacci sequence until the nth term is sufficiently large, and put all the values in a list. My program is as follows:

x = [0, 1]
for j in x:
  if j > 100:
    break
  else:
    x.append(x[-1]+x[-2])
print(x)


In this example, I want it to print out every Fibonacci number less than 100. However, it always prints two more values after my upper bound: in this case, it adds 89 to the list (which I want), followed by 144 and 233. I am wondering if I have a conceptual misunderstanding of how "for _ in _" statement works, as I would've thought it works as follows:
adds first couple of terms fine, then gets to 89, recognises that 89 is less than 100 so adds the next term to the list (144), checks to see if 144 is less than 100, which it isn't, and so does not add 233 to the list.
Apologies if this is a simple mistake, as I said I am new to python.
Thanks.
Reply
#2
Use an infinite generator together with itertools.islice.

from itertools import islice


def fib():
    a, b = 0, 1
    while True:
        yield a
        a, b = a + b, a


fibs = list(islice(fib(), 0, 100))
The yield in the function turns the function into a generator.

Generators: https://realpython.com/introduction-to-p...enerators/
Islice: https://docs.python.org/3/library/iterto...ols.islice
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply
#3
(Jun-10-2020, 02:14 PM)DeaD_EyE Wrote: Use an infinite generator together with itertools.islice.

from itertools import islice


def fib():
    a, b = 0, 1
    while True:
        yield a
        a, b = a + b, a


fibs = list(islice(fib(), 0, 100))
The yield in the function turns the function into a generator.

Generators: https://realpython.com/introduction-to-p...enerators/
Islice: https://docs.python.org/3/library/iterto...ols.islice

Hi Dead_EyE, thank you for your response. This is a much nicer way to write out the Fibonnaci numbers compared to how I did it! Even though what you've posted is much nicer, I'd still be interested in knowing why my original code didn't work.
Thanks.
Reply
#4
Quote:Even though what you've posted is much nicer, I'd still be interested in knowing why my original code didn't work.
That is because you test on j > 100, but j is never the last item.
Test on "if x[-1]+x[-2] > 100:", that is the last item.

Paul
It is more important to do the right thing, than to do the thing right.(P.Drucker)
Better is the enemy of good. (Montesquieu) = French version for 'kiss'.
Reply
#5
Misunderstanding. You meant to have values in the list which are lower than 100.
My example creates a list with exactly 100 elements.

You compared j > 100, which is not the final value.
You've to compare (x[-1] + x[-2]) >= 100.

x = [0, 1]
for j in x:
    result = x[-1] + x[-2]
    if result >= 100:
        # stop is result is bigger or equal to 100
        break
    x.append(result)
print(x)
With my provided example:
from itertools import takewhile, islice


def fib():
    a, b = 0, 1
    while True:
        yield a
        a, b = a + b, a


def condition(value):
    return value < 100


generator = fib()
fibs_below_100 = list(takewhile(condition, generator))
And you can combine different functions from itertools.

Not bigger than 50 and maximum 10 elements:
fib_gen = fib()
fibs_below_50 = takewhile(lambda x: x < 100, fib_gen)
fibs_max_10_elements = islice(fibs_below_50 , 0, 10)

final_result = list(fibs_max_10_elements)
There is one big pitfall, if you use infinite generators:
[x for x in fib if x < 100]
This code will run until you get a MemoryError or hit CTRL+C.
There is no stop condition. Only the decision is made to take x or not.
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply
#6
(Jun-10-2020, 02:54 PM)DPaul Wrote: Misunderstanding. You meant to have values in the list which are lower than 100.
My example creates a list with exactly 100 elements.

You compared j > 100, which is not the final value.
You've to compare (x[-1] + x[-2]) >= 100.

Hi, this explanation and the code you have shown me is extremely helpful and I am very grateful. I find the example using "result = x[-1] + x[-2]" especially intuitive. I just have one final question. Why is j not the final value?
Thanks for all your help.
Reply
#7
The reason you get two extra numbers in the list is because you are testing x[-3] >. You start with two values in x and j never catches up with the end of the list because each time you test the value of j you add a value to x.

If you want to stop at or before 100, use the DeaD_Eye's test. If you want to stop after the first value >= 100 (kind of what your original code looks like) just use:
x = [0, 1]
while x[-1] < 100:
    x.append(x[-1]+x[-2])
print(x)
Reply
#8
Quote: I just have one final question. Why is j not the final value?
I can only explain it the verbose way.
You start with "x = [0,1]", then you say "for j in x:"
So you start with 0 first, which is not the last one, but you are always adding the true last and one-but-last [-1] and [-2]
With the sum you are adding a third item, while the loop now moves to the second one.
So by testing j you are always "late".
Paul
It is more important to do the right thing, than to do the thing right.(P.Drucker)
Better is the enemy of good. (Montesquieu) = French version for 'kiss'.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  How do I calculate a ratio from 2 numbers and return an equivalent list of about 1000 Pleiades 8 15,437 Jan-05-2024, 08:30 PM
Last Post: sgrey
  find random numbers that are = to the first 2 number of a list. Frankduc 23 3,012 Apr-05-2023, 07:36 PM
Last Post: Frankduc
  List of random numbers astral_travel 17 2,533 Dec-02-2022, 10:37 PM
Last Post: deanhystad
  Remove numbers from a list menator01 4 1,251 Nov-13-2022, 01:27 AM
Last Post: menator01
  [split] why can't i create a list of numbers (ints) with random.randrange() astral_travel 7 1,428 Oct-23-2022, 11:13 PM
Last Post: Pedroski55
  Divide a number by numbers in a list. Wallen 7 7,926 Feb-12-2022, 01:51 PM
Last Post: deanhystad
  producing numbers out of a list bouraque7878 10 3,621 Nov-12-2021, 09:13 PM
Last Post: jefsummers
  How to change odd to even numbers in the list? plumberpy 8 3,619 Aug-08-2021, 11:07 AM
Last Post: plumberpy
  convert numbers into list lokesh 1 2,346 Jun-03-2021, 06:37 AM
Last Post: menator01
  Fibonacci Yasunaga 7 2,861 May-16-2021, 02:36 PM
Last Post: csr

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020