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
- Map numeric codes to string labels before calling: ['walk','shop','clean'][code] or use a lookup dict.
- If using sklearn, keep the LabelEncoder and inverse_transform the codes to strings first.
- 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
- inverse_transform label-encoder outputs to strings before use.
- Map numeric codes through a name lookup at ingest.
- Never mix ints and str labels in one observation list.
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
- {var_name} must be a list
- {var_name} must be a dict
- {var_name} all keys must be strings
- {var_name} {nested_text}all values must be {value_type.__nam
- There's an empty parameter
AI-assisted analysis of TheAlgorithms/Python@f5988cc097 (2026-08-14).
Data as JSON: /api/errors/4a9dc361df231886.
Report an issue: GitHub.