How to print a Fibonacci series in Python
Discover multiple ways to print the Fibonacci series in Python. Get tips, see real-world applications, and learn to debug common errors.

The Fibonacci series is a famous mathematical sequence and a great Python coding exercise. It helps you practice fundamental concepts like recursion and iteration to build a fibonacci() function.
Here, you'll find several techniques to print the sequence. You will also get performance tips, see real-world applications, and receive debugging advice to refine your Python skills.
Basic iteration to print Fibonacci series
def print_fibonacci(n):
a, b = 0, 1
fib_series = []
for _ in range(n):
fib_series.append(a)
a, b = b, a + b
return fib_series
print(print_fibonacci(10))--OUTPUT--[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
The print_fibonacci() function uses a straightforward iterative approach. It initializes the first two numbers, 0 and 1, and then loops n times to build the sequence. In each iteration, the current number a is added to the list, following common patterns for creating lists of numbers.
The core of this method is the tuple assignment a, b = b, a + b. This single line efficiently updates the sequence. It simultaneously assigns the value of b to a while calculating the new b from the sum of the previous a and b. This technique avoids the need for a temporary variable, keeping the code concise.
Basic Fibonacci techniques
Beyond the basic iterative loop, you can tackle the Fibonacci sequence with other powerful Python techniques like recursion, list comprehension, and generators.
Using recursion to generate Fibonacci numbers
def fibonacci_recursive(n):
if n <= 0:
return []
elif n == 1:
return [0]
elif n == 2:
return [0, 1]
else:
sequence = fibonacci_recursive(n-1)
sequence.append(sequence[-1] + sequence[-2])
return sequence
print(fibonacci_recursive(10))--OUTPUT--[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
This recursive approach works by breaking the problem into smaller pieces. The fibonacci_recursive function calls itself with a progressively smaller number (n-1) until it hits a defined stopping point, demonstrating key principles of recursion in Python.
- Base cases: The conditions for
n <= 2act as the safety net. They provide a direct answer for the simplest scenarios and prevent an infinite loop. - Recursive step: For any other number, the function calls itself to get the sequence for
n-1. It then appends the new Fibonacci number by summing the last two elements of the returned list.
Generating Fibonacci with list comprehension
def fibonacci_list_comp(n):
fib = [0, 1]
[fib.append(fib[i-1] + fib[i-2]) for i in range(2, n)]
return fib
print(fibonacci_list_comp(10))--OUTPUT--[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
This approach uses a list comprehension for its side effect—modifying a list in place rather than creating a new one. The function initializes fib with the first two numbers, [0, 1].
- The list comprehension then iterates from
2up ton. - In each step, it calls
fib.append()to add the sum of the previous two elements.
It’s a compact alternative to a standard for loop, though the list it generates is immediately discarded since append() returns None.
Creating Fibonacci series using Python generators
def fibonacci_generator(n):
a, b = 0, 1
count = 0
while count < n:
yield a
a, b = b, a + b
count += 1
print(list(fibonacci_generator(10)))--OUTPUT--[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
This generator function is a memory-efficient way to produce the Fibonacci sequence. It uses the yield keyword to produce numbers one by one, on demand, instead of building a full list in memory. Understanding yield in Python is essential for creating effective generators.
- The
yield astatement returns the current number and pauses the function, saving its state. - When the next value is requested, the function resumes right where it left off, updates the numbers, and continues the loop.
To get the final output, you consume the generator—for instance, by converting it into a list with list().
Advanced Fibonacci techniques
When the basic approaches become too slow, you can turn to more powerful techniques like memoization, matrix math, and direct mathematical formulas.
Optimizing with lru_cache for memoization
from functools import lru_cache
@lru_cache(maxsize=None)
def fib(n):
if n < 2:
return n
return fib(n-1) + fib(n-2)
print([fib(i) for i in range(10)])--OUTPUT--[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
The @lru_cache decorator from Python's functools module adds memoization to the recursive fib() function. Memoization is a caching technique—it stores the results of function calls and returns the cached value when the same inputs are used again, avoiding redundant work.
- This is a game-changer for the recursive approach, which otherwise recomputes the same Fibonacci numbers over and over.
- When
fib(n)is called, the decorator checks if the result fornis already in the cache. If so, it's returned instantly. - Setting
maxsize=Nonelets the cache grow without a size limit.
Fast Fibonacci using numpy matrix operations
import numpy as np
def fibonacci_matrix(n):
F = np.array([[1, 1], [1, 0]])
result = [0]
if n > 1:
result.append(1)
for i in range(2, n):
F_powered = np.linalg.matrix_power(F, i-1)
result.append(F_powered[0, 0])
return result
print(fibonacci_matrix(10))--OUTPUT--[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
This method leverages a mathematical shortcut with the numpy library for a highly efficient solution. It’s built on the principle that you can find the nth Fibonacci number by raising a specific 2x2 matrix to the (n-1)th power.
- The function starts with the base matrix
F = np.array([[1, 1], [1, 0]]). - Inside the loop,
np.linalg.matrix_power()calculates the matrix power, which is much faster than repeated multiplication. - The desired Fibonacci number appears in the top-left element of the resulting matrix, which is then appended to the results.
Calculating Fibonacci with Binet's formula
import math
def fibonacci_binet(n):
phi = (1 + math.sqrt(5)) / 2
return [round((phi**i - (1-phi)**i) / math.sqrt(5)) for i in range(n)]
print(fibonacci_binet(10))--OUTPUT--[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
Binet's formula offers a direct mathematical route to any Fibonacci number without iteration. This method relies on the golden ratio, represented as phi in the code. It's a closed-form expression, meaning you can jump straight to the nth number instead of calculating all the preceding ones.
- The function uses a list comprehension to apply the formula for each number up to
n. - Since floating-point math can be imprecise,
round()is crucial for correcting small errors and ensuring the result is a clean integer.
Move faster with Replit
Replit is an AI-powered development platform that comes with all Python dependencies pre-installed, so you can skip setup and start coding instantly. It’s designed to help you move from learning individual techniques to building complete, working applications.
Instead of just piecing together functions, you can use Agent 4 to build the final product. Describe the app you want to create, and the Agent handles everything from the code and databases to APIs and deployment. For example, you could build:
- A financial projection tool that calculates compound interest over a set number of periods.
- A workout planner that generates an incremental exercise routine based on a mathematical sequence.
- A simple animation utility that calculates an object's position frame-by-frame using a recursive function.
Simply describe your app, and Replit will write the code, test it, and fix issues automatically, all within your browser.
Common errors and challenges
Writing Fibonacci functions can introduce tricky errors, but understanding how to handle edge cases and performance limits will keep your code robust. When errors do occur, code repair techniques can help you identify and fix issues quickly.
- Handling negative inputs: The
fibonacci_recursivefunction, as written, doesn't account for negative numbers. If you pass it a negative value, it will enter an infinite recursion until Python raises aRecursionError. A good practice is to handle this edge case explicitly at the start of your function, perhaps by raising aValueErroror returning an empty list to signal invalid input. - Avoiding stack overflow: A pure recursive
fibfunction is elegant but inefficient. It can quickly cause a stack overflow for even moderately large numbers because it recalculates the same values repeatedly. This leads to an exponential number of function calls that can exceed the system's memory limits for the call stack. Using memoization with@lru_cacheis an excellent fix, as it stores results and prevents redundant computations. Alternatively, switching to an iterative approach completely avoids this problem. - Avoiding index errors: An
IndexErroroften occurs when your code tries to access an element that doesn't exist, likesequence[-2]in a list that has fewer than two items. This is common in Fibonacci functions if the base cases aren't handled correctly. Ensuring your function properly initializes the sequence (e.g., with[0, 1]) or has clear stopping conditions for small inputs liken=0orn=1is crucial for preventing these errors.
Handling negative inputs with the fibonacci_recursive function
The current fibonacci_recursive function doesn't crash on negative inputs, but its behavior can be misleading. The if n <= 0: condition makes it return an empty list, silently failing. See what happens when you test it below.
def fibonacci_recursive(n):
if n <= 0:
return []
elif n == 1:
return [0]
elif n == 2:
return [0, 1]
else:
sequence = fibonacci_recursive(n-1)
sequence.append(sequence[-1] + sequence[-2])
return sequence
print(fibonacci_recursive(-5)) # Returns empty list with no error
The function's if n <= 0: condition accepts negative input but returns an empty list, hiding a potential issue. A more robust solution would explicitly signal an error. See how to implement this change below.
def fibonacci_recursive(n):
if n < 0:
raise ValueError("Input must be a non-negative integer")
elif n == 0:
return []
elif n == 1:
return [0]
elif n == 2:
return [0, 1]
else:
sequence = fibonacci_recursive(n-1)
sequence.append(sequence[-1] + sequence[-2])
return sequence
try:
print(fibonacci_recursive(-5))
except ValueError as e:
print(e) # Provides clear error message
By adding a check for n < 0, the function now raises a ValueError for invalid input. It’s a much better approach than silently returning an empty list. This makes your code more predictable by immediately flagging incorrect usage. You can then use a try...except block to catch the error and handle it gracefully. This practice is crucial when writing functions that expect specific input ranges, as it prevents subtle bugs down the line.
Avoiding stack overflow in recursive fib function
While elegant, the standard recursive fib() function is notoriously slow. Each call spawns more calls, creating a massive tree of redundant calculations. This inefficiency quickly consumes memory, risking a stack overflow error. While memoization is the best solution, you can also learn about increasing recursion limits as an alternative approach.
def fib(n):
if n <= 1:
return n
return fib(n-1) + fib(n-2)
print(fib(35)) # Very slow, might cause stack overflow
The fib() function calls itself twice for every number, causing an exponential growth in operations. For a value like 35, this means re-calculating the same results billions of times. The fix is surprisingly simple.
from functools import lru_cache
@lru_cache(maxsize=None)
def fib(n):
if n <= 1:
return n
return fib(n-1) + fib(n-2)
print(fib(35)) # Much faster with memoization
By adding the @lru_cache decorator, you're applying memoization. The function now caches the result of each fib(n) call. If the same number is needed again, the function retrieves the stored value instead of re-running the calculation. This simple change eliminates the exponential number of redundant calls, making the function significantly faster and preventing stack overflow errors. It's a powerful fix for any recursive function with overlapping subproblems.
Avoiding index errors in Fibonacci sequence generation
An IndexError is a common tripwire when generating Fibonacci sequences, especially if your function doesn't correctly handle small inputs like 0 or 1. This error appears when you try to access a list element that doesn't exist. See how it happens below.
def fibonacci_nth_element(n):
fib = [0, 1]
for i in range(2, n):
fib.append(fib[i-1] + fib[i-2])
return fib[n] # IndexError: list index out of range
print(fibonacci_nth_element(10))
The function builds a list with n elements, indexed 0 to n-1. By trying to return fib[n], it requests an index that is one position beyond the list's end. See how to correct this below.
def fibonacci_nth_element(n):
if n < 0:
raise ValueError("Input must be non-negative")
if n == 0:
return 0
fib = [0, 1]
for i in range(2, n+1):
fib.append(fib[i-1] + fib[i-2])
return fib[n]
print(fibonacci_nth_element(10)) # Correctly returns the 10th Fibonacci number
The corrected fibonacci_nth_element() function fixes the IndexError by adjusting its logic. The original error happened because it tried to access fib[n] in a list with only n elements, indexed 0 to n-1. This is a classic off-by-one mistake.
The fix extends the loop to range(2, n+1), ensuring the list is built up to the required index. It also adds checks for n < 0 and n == 0, making the function robust against common edge cases.
Real-world applications
After mastering the code and its common pitfalls, you'll find the Fibonacci sequence has practical uses beyond the terminal, where vibe coding can help you quickly build applications that use these mathematical concepts.
Using Fibonacci for financial market analysis
In financial trading, analysts use Fibonacci ratios to predict potential price support and resistance levels, a technique known as Fibonacci retracement.
def fibonacci_retracement_levels(high, low):
diff = high - low
levels = [0.0, 0.236, 0.382, 0.5, 0.618, 0.786, 1.0]
retracements = {level: round(high - level * diff, 1) for level in levels}
return retracements
stock_high = 150.0
stock_low = 100.0
print(fibonacci_retracement_levels(stock_high, stock_low))
The fibonacci_retracement_levels function uses a dictionary comprehension to map key ratios to specific price points. It first finds the difference between a high and low value. Then, for each predefined ratio in the levels list, it calculates a new price.
- The calculation
high - level * diffdetermines how far the price has moved back from its peak. - The
round()function keeps the output tidy by limiting it to one decimal place.
This creates a dictionary where keys are the Fibonacci ratios and values are the corresponding price levels.
Approximating the golden ratio with consecutive Fibonacci numbers
The ratio of any number in the sequence to the one before it provides a surprisingly accurate approximation of the golden ratio, especially as the numbers get larger.
def golden_ratio_approximation(n=10):
fib_sequence = [0, 1]
for i in range(2, n):
fib_sequence.append(fib_sequence[i-1] + fib_sequence[i-2])
ratios = [fib_sequence[i+1] / fib_sequence[i] for i in range(1, len(fib_sequence)-1)]
return ratios
ratios = golden_ratio_approximation()
for i, ratio in enumerate(ratios, start=1):
print(f"F_{i+1}/F_{i} = {ratio:.6f}")
The golden_ratio_approximation function first builds a Fibonacci sequence of length n. It starts with [0, 1] and uses a loop to append new numbers by summing the previous two. After generating the sequence, it calculates the ratio between consecutive numbers.
- A list comprehension iterates through the sequence, starting from the second number to avoid division by zero.
- For each number, it’s divided by the preceding one using
fib_sequence[i+1] / fib_sequence[i].
The function then returns a list containing these calculated ratios.
Get started with Replit
Turn your new skills into a real application. Tell Replit Agent to “build a tool that calculates Fibonacci retracement levels” or “create a web app that generates spiral art from the sequence.”
The Agent writes the code, tests for errors, and handles deployment for you. Start building with Replit to create your own custom tools.
Describe what you want to build, and Replit Agent writes the code, handles the infrastructure, and ships it live. Go from idea to real product, all in your browser.
Describe what you want to build, and Replit Agent writes the code, handles the infrastructure, and ships it live. Go from idea to real product, all in your browser.



