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.

How to print a Fibonacci series in Python
Published on: 
Fri
Feb 20, 2026
Updated on: 
Mon
Apr 6, 2026
The Replit Team

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 <= 2 act 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 2 up to n.
  • 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 a statement 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 for n is already in the cache. If so, it's returned instantly.
  • Setting maxsize=None lets 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_recursive function, as written, doesn't account for negative numbers. If you pass it a negative value, it will enter an infinite recursion until Python raises a RecursionError. A good practice is to handle this edge case explicitly at the start of your function, perhaps by raising a ValueError or returning an empty list to signal invalid input.
  • Avoiding stack overflow: A pure recursive fib function 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_cache is 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 IndexError often occurs when your code tries to access an element that doesn't exist, like sequence[-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 like n=0 or n=1 is 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 * diff determines 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.

Build your first app today

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.

Build your first app today

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.