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.

Easy Python 3.9+ Aug 9, 2026 Lists & loops 16 views 0 copies

Python code

29 lines
Python 3.9+
def 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

stdout
[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

  1. Use `all(isinstance(item, expected_types) for item in data)` to compress the type check into one line
  2. 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

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from Lists & loops

Related tutorials and quizzes for this topic.