Skip to content

How to Resolve Python "TypeError: cannot unpack non-iterable" (int, float, function, NoneType)

Fix the Python TypeError: cannot unpack non-iterable error when working with integers, floats, functions, or None by ensuring proper iterable unpacking syntax and handling edge cases.

The TypeError: cannot unpack non-iterable <type> object (where <type> is int, float, function, NoneType, etc.) is a common Python error encountered during assignment operations. It arises when you use iterable unpacking syntax (like a, b = value) but the value on the right-hand side is not an iterable (like a list, tuple, or string) or doesn't contain enough items to assign to the variables on the left.

This guide explains why this error occurs for different non-iterable types and provides clear solutions for each case.

Understanding Iterable Unpacking in Python

Iterable unpacking is a convenient Python feature that allows you to assign items from an iterable (like a list, tuple, or string) to multiple variables in a single statement. The number of variables on the left must exactly match the number of items in the iterable on the right.

Example of Unpacking a tuple:

point = (10, 20)
x, y = point # x becomes 10, y becomes 20
print(f"x={x}, y={y}")

Example of Unpacking a list:

data = ["Anna", 24]
name, age = data # name becomes "Anna", age becomes 24
print(f"name={name}, age={age}")

Example of Unpacking a string (iterable of characters):

s1, s2, s3 = "xyz" # s1='x', s2='y', s3='z'
print(f"s1={s1}, s2={s2}, s3={s3}")

Output:

x=10, y=20
name=Anna, age=24
s1=x, s2=y, s3=z

The Core Problem: Trying to Unpack Non-Iterables

The TypeError: cannot unpack non-iterable ... object occurs when the object on the right side of the unpacking assignment is not something Python can iterate over to extract multiple items. Integers, floats, functions themselves (without being called), and the None object fall into this category – they represent single entities, not sequences of items in this context.

Case 1: int or float Objects

You can not directly unpack a single number into multiple variables.

The Problem: a, b = 10 or a, b = 3.14

try:
  var1, var2 = 100
except TypeError as e:
  print(f"Integer unpacking error: {e}")

try:
  f1, f2 = 3.14159
except TypeError as e:
  print(f"Float unpacking error: {e}")

Integers and floats are single numeric values, not collections of values to be unpacked.

Solution: Unpack an Actual Iterable (List/Tuple)

If you intend to assign multiple values, provide them within an iterable like a tuple or list.

a, b = (100, 200)
print(f"a={a}, b={b}")          # Output: a=100, b=200

f1, f2 = [3.14, 2.71]
print(f"f1={f1}, f2={f2}")      # Output: f1=3.14, f2=2.71

x = y = z = 0 # Assign 0 to z, then z's value to y, then y's value to x
print(f"x={x}, y={y}, z={z}")   # Output: x=0, y=0, z=0

Assigning Digits of a Number (Workaround)

If the goal was to get individual digits, convert the number to a string (which is iterable) first. Remember the results will be strings.

number = 456
digit_str1, digit_str2, digit_str3 = str(number)                    # Unpack the string "456"

print(f"Digit 1: '{digit_str1}' (type: {type(digit_str1)})")        # Output: '4' (<class 'str'>)
print(f"Digit 2: '{digit_str2}'")                                   # Output: '5'
print(f"Digit 3: '{digit_str3}'")                                   # Output: '6'

digit_int1 = int(digit_str1)
print(f"Digit 1 as int: {digit_int1} (type: {type(digit_int1)})")   # Output: 4 (<class 'int'>)

Case 2: function Object

This typically happens when you forget the parentheses () needed to call the function, and instead try to unpack the function object itself.

The Problem: a, b = my_function (Forgetting ())

def get_coordinates():
  return (10, 50) # Function returns a tuple

try:
  x, y = get_coordinates # Missing parentheses ()
except TypeError as e:
  print(f"Function unpacking error: {e}")

Solution: Call the Function a, b = my_function()

Ensure you call the function using parentheses (). The unpacking then applies to the value returned by the function (which must be an iterable like a list or tuple).

def get_coordinates():
  return (10, 50)                                   # Returns an iterable tuple

x, y = get_coordinates()
print(f"Coordinates: x={x}, y={y}")                 # Output: Coordinates: x=10, y=50

def get_data(id):
    return ["Data", id, True]                       # Returns a list

item_name, item_id, status = get_data(123)          # Call with arguments
print(f"Data: {item_name}, {item_id}, {status}")    # Output: Data: Data, 123, True

Case 3: NoneType Object

The None object represents the absence of a value and is not iterable.

The Problem: a, b = None or Function Returned None

This can happen if a variable is explicitly None, or more commonly, if a function you expected to return an iterable actually returned None. Functions return None implicitly if they lack a return statement, or explicitly via return None. Many in-place list methods (like .sort(), .append()) also return None.

def process_data(data):
  if len(data) > 0:
     processed = [d * 2 for d in data]

result = process_data([1, 2]) # result will be None
print(f"Result from function: {result}") # Output: None

try:
    val1, val2 = result # Trying to unpack None
except TypeError as e:
    print(f"None unpacking error: {e}")

my_list = [3, 1, 2]
try:
    s1, s2, s3 = my_list.sort()
except TypeError as e:
    print(f"Sort() return error: {e}")

Solution: Check for None, Provide Defaults, Fix Function Returns

  • Fix the Function: Ensure the function consistently returns an iterable (list, tuple) with the expected number of elements in all code paths. Add return statements where needed.
    def process_data_fixed(data):
      if len(data) > 0:
         processed = [d * 2 for d in data]
         return processed                               # ✅ Explicitly return the list
      return []                                         # ✅ Return an empty list if input is empty
    
    result_fixed = process_data_fixed([1, 2])
    val1, val2 = result_fixed # Now works!
    print(f"Fixed result: val1={val1}, val2={val2}")    # Output: val1=2, val2=4
  • Check for None Before Unpacking: If a function might legitimately return None, check for it before attempting to unpack.
    result_might_be_none = process_data([])             # Returns None from original function
    
    if result_might_be_none is not None:
        if hasattr(result_might_be_none, '__iter__'):   # Check if iterable
           val1, val2 = result_might_be_none
           print("Unpacked successfully")
        else:
            print("Result is not None, but not iterable for unpacking.")
    else:
        print("Result was None, cannot unpack.")        # This is executed
  • Provide a Default Iterable: If you get None, assign a default tuple/list before unpacking.
    result_is_none = None
    val1, val2 = result_is_none if result_is_none is not None else (0, 0)
    print(f"Unpacking with default: val1={val1}, val2={val2}") 

Note on In-Place Methods (like list.sort())

Methods that modify an object in-place (like list.sort(), list.append(), list.reverse()) usually return None. Don't try to unpack the return value of these methods. Perform the operation first, then unpack the modified object itself if needed.

my_list = [3, 1, 2]
my_list.sort()                      # Sorts the list in-place, returns None
print(f"Sorted list: {my_list}")    # Output: [1, 2, 3]

s1, s2, s3 = my_list
print(f"s1={s1}, s2={s2}, s3={s3}") # Output: s1=1, s2=2, s3=3

Debugging the Error

Check the Type of the Object (type(), isinstance())

When you get this error, the first step is to check the type of the object you're trying to unpack.

value_to_unpack = 10 # Example value

print(f"Value: {value_to_unpack}, Type: {type(value_to_unpack)}")

print(f"Is it iterable? {hasattr(value_to_unpack, '__iter__')}")

This confirms if the object is indeed non-iterable as the error message suggests.

A similar error can occur in for loops if you try to unpack items from an iterable where the items themselves are not iterable (or don't have the expected number of sub-items).

data = [10, 20, 30] # List of integers

try:
    for index, value in data:
        print(index, value)
except TypeError as e:
    print(f"For loop unpacking error: {e}")

print("Correct loop with enumerate():")
for index, value in enumerate(data):
    print(index, value)

Output:

For loop unpacking error: cannot unpack non-iterable int object
Correct loop with enumerate():
0 10
1 20
2 30

Conclusion

The TypeError: cannot unpack non-iterable <type> object signals that you are attempting iterable unpacking (a, b = value) on a value that Python doesn't consider a sequence or collection in that context (like int, float, function, or None).

  • Solution: Ensure the object on the right-hand side of the assignment is an iterable (list, tuple, string, etc.) containing the exact number of items as variables on the left.
  • When dealing with function results, make sure you call the function (my_func()) and that it returns an appropriate iterable.
  • Be cautious with values that might be None; check for None or ensure functions return valid iterables in all cases.
  • Do not try to unpack the None returned by in-place methods like list.sort().

By verifying the type of object being unpacked and ensuring it's a suitable iterable, you can easily resolve this common Python error.

Navigation