{"record":{"id":"4a9dc361df231886","repo":"TheAlgorithms/Python","slug":"var-name-must-be-a-list-of-strings","errorCode":null,"errorMessage":"{var_name} must be a list of strings","messagePattern":"(.+?) must be a list of strings","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"dynamic_programming/viterbi.py","lineNumber":283,"sourceCode":"    \"\"\"\n    >>> _validate_list([\"a\"], \"mock_name\")\n    >>> _validate_list(\"a\", \"mock_name\")\n    Traceback (most recent call last):\n            ...\n    ValueError: mock_name must be a list\n    >>> _validate_list([0.5], \"mock_name\")\n    Traceback (most recent call last):\n            ...\n    ValueError: mock_name must be a list of strings\n    \"\"\"\n    if not isinstance(_object, list):\n        msg = f\"{var_name} must be a list\"\n        raise ValueError(msg)\n    else:\n        for x in _object:\n            if not isinstance(x, str):\n                msg = f\"{var_name} must be a list of strings\"\n                raise ValueError(msg)\n\n\ndef _validate_dicts(\n    initial_probabilities: Any,\n    transition_probabilities: Any,\n    emission_probabilities: Any,\n) -> None:\n    \"\"\"\n    >>> _validate_dicts({\"c\":0.5}, {\"d\": {\"e\": 0.6}}, {\"f\": {\"g\": 0.7}})\n    >>> _validate_dicts(\"invalid\", {\"d\": {\"e\": 0.6}}, {\"f\": {\"g\": 0.7}})\n    Traceback (most recent call last):\n            ...\n    ValueError: initial_probabilities must be a dict\n    >>> _validate_dicts({\"c\":0.5}, {2: {\"e\": 0.6}}, {\"f\": {\"g\": 0.7}})\n    Traceback (most recent call last):\n            ...\n    ValueError: transition_probabilities all keys must be strings\n    >>> _validate_dicts({\"c\":0.5}, {\"d\": {\"e\": 0.6}}, {\"f\": {2: 0.7}})","sourceCodeStart":265,"sourceCodeEnd":301,"githubUrl":"https://github.com/TheAlgorithms/Python/blob/f5988cc09713315817df6a7e327e258013a94440/dynamic_programming/viterbi.py#L265-L301","documentation":"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.","triggerScenarios":"Calling viterbi([0, 1], ['rainy','sunny'], ...) with integer observation codes; a list containing floats ([0.5]) or None; mixed lists like ['walk', 2].","commonSituations":"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.","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."],"exampleFix":"# before\nviterbi([0, 1, 2], ['rainy','sunny'], initial_p, trans_p, emit_p)  # ValueError\n\n# after\nobs_names = ['walk', 'shop', 'clean']\nviterbi([obs_names[c] for c in [0, 1, 2]], ['rainy','sunny'], initial_p, trans_p, emit_p)","handlingStrategy":"validation","validationCode":"def to_label_list(codes, names) -> list[str]:\n    return [names[c] if isinstance(c, int) else str(c) for c in codes]","typeGuard":"def is_str_list(x: object) -> TypeGuard[list[str]]:\n    return isinstance(x, list) and all(isinstance(i, str) for i in x)","tryCatchPattern":null,"preventionTips":["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."],"tags":["dynamic-programming","hmm","type-validation"],"backgroundTag":null,"analyzedSha":"f5988cc09713315817df6a7e327e258013a94440","analyzedAt":"2026-08-14T17:30:07.041Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}