How to Resolve Python "TypeError: cannot unpack non-iterable ... object" (int, float, function, NoneType)
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:
# ⛔️ TypeError: cannot unpack non-iterable int object
var1, var2 = 100
except TypeError as e:
print(f"Integer unpacking error: {e}")
try:
# ⛔️ TypeError: cannot unpack non-iterable float object
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.
# ✅ Unpack from a tuple
a, b = (100, 200)
print(f"a={a}, b={b}") # Output: a=100, b=200
# ✅ Unpack from a list
f1, f2 = [3.14, 2.71]
print(f"f1={f1}, f2={f2}") # Output: f1=3.14, f2=2.71
# ✅ Initialize multiple variables to the same value (different concept)
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'
# Convert back to int if needed
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:
# ⛔️ TypeError: cannot unpack non-iterable function object
# Trying to unpack the function object itself, not its return value
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
# ✅ Call the function and unpack its returned 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:
# Forgets to return the processed data
processed = [d * 2 for d in data]
# No return statement, so function returns None implicitly
result = process_data([1, 2]) # result will be None
print(f"Result from function: {result}") # Output: None
try:
# ⛔️ TypeError: cannot unpack non-iterable NoneType object
val1, val2 = result # Trying to unpack None
except TypeError as e:
print(f"None unpacking error: {e}")
my_list = [3, 1, 2]
try:
# ⛔️ TypeError: cannot unpack non-iterable NoneType object
# list.sort() modifies the list in-place and returns None
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 returnNone
, 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:
# Only unpack if it's not None and is iterable
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
# Use a default if None is received
val1, val2 = result_is_none if result_is_none is not None else (0, 0)
print(f"Unpacking with default: val1={val1}, val2={val2}")
# Output: Unpacking with default: val1=0, val2=0
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]
# ✅ Now unpack the modified list
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)}")
# Output: Value: 10, Type: <class 'int'>
print(f"Is it iterable? {hasattr(value_to_unpack, '__iter__')}")
# Output: Is it iterable? False (Integers are not iterable for unpacking)
This confirms if the object is indeed non-iterable as the error message suggests.
Related Error in for
Loops**
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:
# ⛔️ TypeError: cannot unpack non-iterable int object
# Trying to unpack each 'item' (which is an int like 10) into 'index' and 'value'
for index, value in data:
print(index, value)
except TypeError as e:
print(f"For loop unpacking error: {e}")
# ✅ Correct way to get index and value: use enumerate()
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 forNone
or ensure functions return valid iterables in all cases. - Do not try to unpack the
None
returned by in-place methods likelist.sort()
.
By verifying the type of object being unpacked and ensuring it's a suitable iterable, you can easily resolve this common Python error.