TheAlgorithms/Python · error · ValueError

{var_name} must be a list of strings

Error message

{var_name} must be a list of strings

What it means

Raised by viterbi's _validate_list when the object is a list but one or more of its elements is not a str. The observation and state spaces are symbolic labels, not numbers — probabilities live in the separate dict parameters — so numeric labels like [0, 1] or [0.5] are rejected with the parameter name in the message.

Source

Thrown at dynamic_programming/viterbi.py:283

    """
    >>> _validate_list(["a"], "mock_name")
    >>> _validate_list("a", "mock_name")
    Traceback (most recent call last):
            ...
    ValueError: mock_name must be a list
    >>> _validate_list([0.5], "mock_name")
    Traceback (most recent call last):
            ...
    ValueError: mock_name must be a list of strings
    """
    if not isinstance(_object, list):
        msg = f"{var_name} must be a list"
        raise ValueError(msg)
    else:
        for x in _object:
            if not isinstance(x, str):
                msg = f"{var_name} must be a list of strings"
                raise ValueError(msg)


def _validate_dicts(
    initial_probabilities: Any,
    transition_probabilities: Any,
    emission_probabilities: Any,
) -> None:
    """
    >>> _validate_dicts({"c":0.5}, {"d": {"e": 0.6}}, {"f": {"g": 0.7}})
    >>> _validate_dicts("invalid", {"d": {"e": 0.6}}, {"f": {"g": 0.7}})
    Traceback (most recent call last):
            ...
    ValueError: initial_probabilities must be a dict
    >>> _validate_dicts({"c":0.5}, {2: {"e": 0.6}}, {"f": {"g": 0.7}})
    Traceback (most recent call last):
            ...
    ValueError: transition_probabilities all keys must be strings
    >>> _validate_dicts({"c":0.5}, {"d": {"e": 0.6}}, {"f": {2: 0.7}})

View on GitHub (pinned to f5988cc097)

Solutions

  1. Map numeric codes to string labels before calling: ['walk','shop','clean'][code] or use a lookup dict.
  2. If using sklearn, keep the LabelEncoder and inverse_transform the codes to strings first.
  3. Use str(o) for simple cases where the numeric id itself is an acceptable label.

Example fix

# before
viterbi([0, 1, 2], ['rainy','sunny'], initial_p, trans_p, emit_p)  # ValueError

# after
obs_names = ['walk', 'shop', 'clean']
viterbi([obs_names[c] for c in [0, 1, 2]], ['rainy','sunny'], initial_p, trans_p, emit_p)
Defensive patterns

Strategy: validation

Validate before calling

def to_label_list(codes, names) -> list[str]:
    return [names[c] if isinstance(c, int) else str(c) for c in codes]

Type guard

def is_str_list(x: object) -> TypeGuard[list[str]]:
    return isinstance(x, list) and all(isinstance(i, str) for i in x)

Prevention

When it happens

Trigger: Calling viterbi([0, 1], ['rainy','sunny'], ...) with integer observation codes; a list containing floats ([0.5]) or None; mixed lists like ['walk', 2].

Common situations: Encoding observations as integer class codes from a sklearn label encoder and passing them raw; converting categorical data to numeric ids upstream; forgetting to map numeric state ids back to string names after preprocessing.

Related errors


AI-assisted analysis of TheAlgorithms/Python@f5988cc097 (2026-08-14). Data as JSON: /api/errors/4a9dc361df231886. Report an issue: GitHub.