To determine if an object is iterable in Python (i.e., can be used in loops like for
or with iter()
), you can use the following methods:
1. Check Using collections.abc.Iterable
The standard way to check if an object is iterable (supports __iter__
method).
Note: This works for most built-in iterables but may miss objects that use __getitem__
for iteration.
from collections.abc import Iterable
def is_iterable(obj):
return isinstance(obj, Iterable)
# Examples:
print(is_iterable([1, 2, 3])) # True (list is iterable)
print(is_iterable("hello")) # True (string is iterable)
print(is_iterable(123)) # False (int is not iterable)
2. Attempt to Call iter()
(EAFP Principle)
A more reliable method that works for objects using __iter__
or __getitem__
for iteration.
Pythonic approach: “Easier to Ask for Forgiveness than Permission” (EAFP).
def is_iterable(obj):
try:
iter(obj)
return True
except TypeError:
return False
# Examples:
print(is_iterable({"a": 1})) # True (dict is iterable)
print(is_iterable(3.14)) # False (float is not iterable)
# Works for custom classes with __getitem__
class MySequence:
def __getitem__(self, index):
return index
my_seq = MySequence()
print(is_iterable(my_seq)) # True (uses __getitem__)
3. Check for __iter__
or __getitem__
(Advanced)
Explicitly check for iteration methods (covers most cases, but not foolproof).
def is_iterable(obj):
return hasattr(obj, '__iter__') or hasattr(obj, '__getitem__')
# Example:
class CustomIterable:
def __iter__(self):
yield 1
class CustomSequence:
def __getitem__(self, index):
return index
print(is_iterable(CustomIterable())) # True (has __iter__)
print(is_iterable(CustomSequence())) # True (has __getitem__)
print(is_iterable(True)) # False (bool has neither)
Key Differences
Method | Covers __iter__ | Covers __getitem__ | Notes |
---|---|---|---|
collections.abc.Iterable | Yes | No | Misses old-style sequences. |
iter() + try/except | Yes | Yes | Most reliable, but slower. |
Check __iter__ /__getitem__ | Yes | Yes | May include non-iterable objects. |
Examples of Iterable Objects
- Built-in:
list
,str
,dict
,set
,tuple
,generator
- Custom Classes: Objects with
__iter__
or__getitem__
methods. - Files: Open file handles (e.g.,
with open(...) as f
).
Non-Iterable Objects
- Primitives:
int
,float
,bool
,None
- Non-iterable classes: Objects without
__iter__
or__getitem__
.
When to Use Which?
- Use
collections.abc.Iterable
for standard iterables (e.g., lists, strings). - Use the
iter()
+ try/except approach for edge cases (e.g., custom sequences). - Avoid checking
__iter__
/__getitem__
directly unless necessary.
Final Recommendation
Use the iter()
+ try/except method for reliability across all iterable types:
def is_iterable(obj):
try:
iter(obj)
return True
except TypeError:
return False