How to Validate List Data in Python
A beginner-friendly validation helper that checks if data is a list, enforces minimum length, and optionally verifies item types with clear error messages.
Python code
29 linesdef validate_data(data, expected_types=None, min_length=1):
"""Validate that data is a non-empty list and optionally check item types."""
if not isinstance(data, list):
return False, f"Expected a list, got {type(data).__name__}"
if len(data) < min_length:
return False, f"List must have at least {min_length} item(s), got {len(data)}"
if expected_types:
for i, item in enumerate(data):
if not isinstance(item, expected_types):
return False, f"Item at index {i} has type {type(item).__name__}, expected {expected_types.__name__}"
return True, f"Valid list with {len(data)} item(s)"
if __name__ == "__main__":
# Test cases
test_data = [
([1, 2, 3], int, 1),
(["a", "b"], str, 2),
([], None, 1),
(42, None, 1),
([1, "two", 3], int, 1),
]
for data, exp_types, min_len in test_data:
is_valid, message = validate_data(data, exp_types, min_len)
print(f"{data!r:20} -> {is_valid}: {message}")
Output
[1, 2, 3] -> True: Valid list with 3 item(s)
['a', 'b'] -> True: Valid list with 2 item(s)
[] -> False: List must have at least 1 item(s), got 0
42 -> False: Expected a list, got int
[1, 'two', 3] -> False: Item at index 1 has type str, expected int
How it works
The isinstance check gates every validation step so non-list inputs fail fast with a descriptive message. The min_length parameter defaults to 1 but is configurable, letting callers require empty lists when needed. When expected_types is provided, the enumerate loop pairs each item with its index so errors pinpoint the exact problem location. Returning a tuple (bool, str) keeps the function test-friendly and easy to use in conditional logic. This helper scales from toy scripts to real form or API validation with minimal changes.
Common mistakes
- Forgetting the `enumerate` index and only reporting the bad item, not its position
- Passing a tuple like `(int, float)` when you only want one type — use `(int, float)` clarity or union types
- Checking `len(data)` before `isinstance(data, list)` and crashing on non-list inputs
- Hardcoding `min_length=1` when valid empty lists are acceptable in some workflows
Variations
- Use `all(isinstance(item, expected_types) for item in data)` to compress the type check into one line
- Allow `expected_types` to be a tuple of multiple acceptable types (e.g., `(int, float)`)
Real-world use cases
- Sanitizing user input in a web form before updating a database record.
- Checking API payloads to ensure required array fields meet minimum size and type contracts.
- Validating batch process arguments in a CLI tool before running transformations.
Sponsored
More from Lists & loops
- Check if List is Sorted Ascending in Python easy
- Compare Two Lists in Python: Common, Only in First, Only in Second easy
- Convert a List of Integers to a Comma-Separated String in Python easy
- Enumerate a Python List with a Custom Start Index easy
- Extract Data by Type from a List in Python: Numbers and Strings easy
- Find All Occurrences of an Item in a Python List easy
Keep learning
Related tutorials and quizzes for this topic.