Int Object Is Not Iterable | Fix It Fast In Python

Int object is not iterable means your code tried to loop over a number; change the data shape or return an iterable value.

You hit this error when Python expects something it can loop through, but it receives a plain integer instead. It can show up in a for loop, in unpacking, in functions like sum(), or inside a library call that iterates under the hood. The fix is almost always about shape. You wanted a list, tuple, set, string, range, dict, or generator, but you handed over a single number.

This guide stays practical. You’ll see what triggers the error, how to spot the exact line that caused it, and a set of repair patterns you can reuse across scripts, notebooks, and production code.

What The Error Message Is Telling You

Python uses the word “iterable” for values that can be stepped through one item at a time. Lists are iterable. Tuples are iterable. Strings are iterable. A plain integer is not. When code tries to do iteration on an integer, Python raises TypeError with the message you’re seeing.

Iteration can be obvious, like looping. It can also be indirect. Many functions accept “a thing with many items” and quietly iterate inside. That’s why the error can appear in places that don’t look like loops.

  • Read The Traceback From Bottom Up — Start at the last line; that’s where Python decided it could not iterate.
  • Find The First Line In Your File — That line is usually where the integer entered a path that expects many items.
  • Look For An Iteration Signal — Common signals are for x in ..., list(...), tuple(...), set(...), zip(...), unpacking like a, b = ..., or a star like *value.

Common Places Where Integers Get Treated Like Collections

The error often comes from a mismatch between what a function returns and what the caller expects. It also happens when a variable name suggests a collection, yet it stores a count. The safest move is to check both the value and its type right where you pass it onward.

Where It Shows Up What You Passed What To Do
for item in n An integer count Use range(n) or loop over a list
sum(n) A single number Sum a list like sum(nums), or skip sum
list.extend(n) An integer Use append for one item, or pass a list
a, b = n An integer Return a tuple like (a, b), not a count
zip(n, items) An integer Zip two iterables, or create a repeated iterable

One sneaky source is JSON. A field that sometimes holds a list may hold a single number in older records. When you parse it, normalize the field to a list before you loop in your code.

  • Counts Versus Lists — A name like items should hold items, not a count like len(items).
  • IDs Versus Records — A name like user_ids should be a list of IDs, not one ID.
  • Return Values Versus Status Codes — If a function sometimes returns a list and sometimes returns 0, callers will trip.

Int Object Is Not Iterable Error In Python With Fast Root Causes

When you see int object is not iterable, aim to answer one question: “Where did this integer come from?” Once you find the source, the fix tends to be simple. Below are the patterns that cause the bug most often, along with clean repairs.

Looping Over A Count Instead Of A Range

A beginner-friendly trap is looping over a number you meant as a loop count. Python needs an iterable in the in slot.

# buggy
n = 5
for i in n:
    print(i)
# fixed
n = 5
for i in range(n):
    print(i)
  • Use Range For Repeat Loops — Replace for i in n with for i in range(n).
  • Loop Over Data When You Have It — If you already have a list, loop over the list, not its length.

Extending A List With A Single Number

extend takes an iterable and adds each element. That makes it great for adding many items. When you have one number, use append.

# buggy
nums = [1, 2]
nums.extend(3)
# fixed
nums = [1, 2]
nums.append(3)
  • Pick Append For One Itemappend adds the integer as one element.
  • Wrap One Item When Extend Is Required — Use extend([3]) if you must keep extend.

Unpacking A Single Integer

Unpacking expects a sequence with the right number of items. If a function returns one integer, unpacking will fail.

# buggy
x, y = 10
# fixed
x, y = (10, 20)
  • Return Tuples For Multiple Outputs — Use return a, b in the function.
  • Store Single Values In One Name — Use x = 10 when there is only one value.

Mixing Return Types Across Branches

This one bites even seasoned coders. A function returns a list on success, but returns an integer on failure. Then a caller iterates the result and crashes.

def get_scores(user_id):
    data = fetch_scores(user_id)
    if data is None:
        return 0   # buggy shape
    return data
def get_scores(user_id):
    data = fetch_scores(user_id)
    if data is None:
        return []  # fixed shape
    return data
  • Keep A Stable Shape — Return an empty list instead of 0 when the caller loops.
  • Use Exceptions For Errors — Raise an error for failure states instead of returning a number.

Repair Patterns You Can Apply In Minutes

Once you know where the integer enters an iterable path, pick a repair pattern that matches your intent. These are the ones you’ll use most.

Wrap A Single Value Into A One-Item Iterable

If downstream code is built around iterables, wrapping can be the cleanest option. It keeps call sites simple and keeps the data shape steady.

  • Use Square Brackets For A List — Turn n into [n] when one item is fine.
  • Use A Trailing Comma For A Tuple — Write (n,) when you need a tuple.
  • Use Set Braces With Care — Use {n} for a set when you need no duplicates.

Generate A Sequence From A Count

If the integer is a count, make an iterable that represents the repetition. The usual choice is range. It’s memory-friendly and works in loops and comprehensions.

  • Use Range For Indexesrange(n) yields 0 through n-1.
  • Use Range With A Startrange(start, stop) matches many slice-style tasks.
  • Use Repeat For Same Valueitertools.repeat(n, times) yields the same value many times.

Convert The Upstream Value To The Right Type

Sometimes the integer is a symptom of a parsing step that lost structure. Say you split a string but then cast one part to int too early. In those cases, keep the data as a list until the moment you need the number.

  • Delay Int Casting — Keep strings in a list, then cast each item during iteration.
  • Cast Collections, Not Scalars — Use map(int, parts) or a list comprehension to build a list of ints.
  • Validate Input Shape — If a function accepts “one or many,” normalize to a list right away.

Debugging Steps That Pinpoint The Real Line

When the traceback points into a library, it can feel like the bug is outside your code. In practice, your code still passed the integer in. Use a tight workflow to find the handoff point and fix it once.

Print Type And Value Right Before The Crash

Add a single print at the call site. Remove it after the fix. Keep it surgical so you don’t drown in logs.

print(value, type(value))
  • Check The Shape At Boundaries — Print right before you pass a value into a function or loop.
  • Check After Parsing — Print right after reading files, JSON, forms, or CLI args.

Use Guard Clauses To Fail Early

Guards can turn a confusing deep traceback into a clear local error. They also document what your function expects.

from collections.abc import Iterable

def process(items):
    if isinstance(items, int):
        raise TypeError("process() needs an iterable, not an int")
    # proceed with iteration
  • Reject Int Inputs — If an integer makes no sense, fail right away.
  • Normalize One Or Many — If you accept either, convert int to [int] near the top.

Trace The Data Back Through Assignments

Once you know a name holds an integer, jump back to where that name was set. Look for calls to len(), integer casts, counters, or numeric defaults.

  • Search For The Variable Name — Scan for reassignment that changes a list into a count.
  • Watch For Shadowing — A loop index named items can overwrite an outer list named items.
  • Check Function Returns — A return that swaps between list and int is a common trigger.

Patterns That Prevent The Error From Coming Back

After you fix the immediate crash, a small bit of structure can keep the same bug from reappearing in a month. You don’t need heavy ceremony. A few habits go a long way.

Name Variables By Shape

Names can carry shape hints. Plural names suggest many items. Singular names suggest one item. That makes it easier to spot a mismatch while reading.

  • Use Plurals For Iterablesusers, scores, rows.
  • Use Count Suffixes For Numbersuser_count, row_total.
  • Use Id For One Identifieruser_id for one int, user_ids for many.

Keep Return Types Stable

If callers loop over your return value, always return an iterable, even when the result is empty. Reserve integers for counts and status codes that callers never iterate.

  • Return Empty Lists On No Data — An empty list is safe to loop over.
  • Raise Errors On Failure — Exceptions keep shapes consistent and keep failures loud.
  • Document The Contract — A short docstring that states the return type can prevent misuse.

Use Type Hints And Static Checks

Type hints can catch “int passed where iterable expected” before runtime. Even if you don’t run a full type checker, hints improve editor feedback and code review clarity.

from typing import Iterable

def total(values: Iterable[int]) -> int:
    return sum(values)
  • Add Hints At Public Boundaries — Start with functions that are called from many places.
  • Run A Type Checker In CI — Tools like mypy can flag shape mismatches early.

If you’re seeing this crash in a new codebase, fix the first one, then search for the same pattern elsewhere. Once you train your eyes to spot “count passed as collection,” the int object is not iterable error stops being mysterious and turns into a quick shape check.