TheAlgorithms/Python · error · ValueError
Expecting an iterable object but got an non-iterable type {p
Error message
Expecting an iterable object but got an non-iterable type {points} What it means
Raised by _validate_input() in divide_and_conquer/convex_hull.py:179 when the points argument has no __iter__ attribute — i.e. passing a single scalar like an int, float, or None where an iterable of (x, y) points is required. It is the first of two validation stages: non-iterable raises this; an empty iterable raises the sibling 'Expecting a list of points' error.
Source
Thrown at divide_and_conquer/convex_hull.py:179
>>> _validate_input([[1, 2]])
[(1.0, 2.0)]
>>> _validate_input([(1, 2)])
[(1.0, 2.0)]
>>> _validate_input([Point(2, 1), Point(-1, 2)])
[(2.0, 1.0), (-1.0, 2.0)]
>>> _validate_input([])
Traceback (most recent call last):
...
ValueError: Expecting a list of points but got []
>>> _validate_input(1)
Traceback (most recent call last):
...
ValueError: Expecting an iterable object but got an non-iterable type 1
"""
if not hasattr(points, "__iter__"):
msg = f"Expecting an iterable object but got an non-iterable type {points}"
raise ValueError(msg)
if not points:
msg = f"Expecting a list of points but got {points}"
raise ValueError(msg)
return _construct_points(points)
def _det(a: Point, b: Point, c: Point) -> float:
"""
Computes the sign perpendicular distance of a 2d point c from a line segment
ab. The sign indicates the direction of c relative to ab.
A Positive value means c is above ab (to the left), while a negative value
means c is below ab (to the right). 0 means all three points are on a straight line.
As a side note, 0.5 * abs|det| is the area of triangle abc
ParametersView on GitHub (pinned to f5988cc097)
Solutions
- Always pass a collection of coordinate pairs: convex_hull([(x1,y1),(x2,y2),...])
- Check for None explicitly before calling when the data source can return None
- Guard with isinstance(points, (list, tuple)) and verify each element is a length-2 sequence
Example fix
// before hull = convex_hull(point) # point = (3, 4) -> silently wrong; point = 3 -> ValueError # after points = [point] if isinstance(point, tuple) and len(point) == 2 else point hull = convex_hull(points)
Defensive patterns
Strategy: type-guard
Validate before calling
if points is None or isinstance(points, (int, float)):
raise ValueError('points must be an iterable of (x, y) pairs')
hull = convex_hull(points) Type guard
def is_points_collection(points) -> bool:
return hasattr(points, '__iter__') and len(points) > 0 and all(
hasattr(p, '__len__') and len(p) == 2 for p in points
) Try / catch
try:
hull = convex_hull(points)
except ValueError as e:
if 'non-iterable' not in str(e) and 'list of points' not in str(e):
raise
hull = None Prevention
- Check data sources for None before calling — the most common non-iterable input
- A single (x, y) tuple passes the iterable check and is treated as 2 points of wrong shape; wrap it in a list first
When it happens
Trigger: convex_hull(1), convex_hull(None), or convex_hull((3, 4)) where a single point tuple is passed instead of a collection of points — note a tuple IS iterable, so a lone point is accepted and misinterpreted, not rejected here.
Common situations: Calling the hull function with the result of a function that sometimes returns None (empty search), or unwrapping a list one level too many before passing it in.
Related errors
- number must be positive
- The value of input must be non-negative
- Input list must contain at least two elements
- Inputs and select signal must be 0 or 1
- plain must contain only lowercase letters (a-z)
AI-assisted analysis of TheAlgorithms/Python@f5988cc097 (2026-08-14).
Data as JSON: /api/errors/ccde87ede3479854.
Report an issue: GitHub.