TheAlgorithms/Python · error · ValueError

{var_name} {nested_text}all values must be {value_type.__nam

Error message

{var_name} {nested_text}all values must be {value_type.__name__}

What it means

Raised by viterbi's _validate_dict when the dict has string keys but one or more values are not of the expected type (float for probability tables). Initial probabilities map state->float; transition/emission tables map state->dict-of-floats (validated with nested=True, which prefixes 'nested dictionary' to the message). Ints like {'b': 4} fail because Python treats int and float as distinct under isinstance.

Source

Thrown at dynamic_programming/viterbi.py:371

    >>> _validate_dict({2: 0.5}, "mock_name",float, True)
    Traceback (most recent call last):
            ...
    ValueError: mock_name all keys must be strings
    >>> _validate_dict({"b": 4}, "mock_name", float,True)
    Traceback (most recent call last):
            ...
    ValueError: mock_name nested dictionary all values must be float
    """
    if not isinstance(_object, dict):
        msg = f"{var_name} must be a dict"
        raise ValueError(msg)
    if not all(isinstance(x, str) for x in _object):
        msg = f"{var_name} all keys must be strings"
        raise ValueError(msg)
    if not all(isinstance(x, value_type) for x in _object.values()):
        nested_text = "nested dictionary " if nested else ""
        msg = f"{var_name} {nested_text}all values must be {value_type.__name__}"
        raise ValueError(msg)


if __name__ == "__main__":
    from doctest import testmod

    testmod()

View on GitHub (pinned to f5988cc097)

Solutions

  1. Write all probabilities as floats: use 1.0, 0.0, 0.7 — not 1, 0, or integer results.
  2. Normalize tables once: {k: {s: float(v) for s, v in row.items()} for k, row in table.items()}.
  3. Prefer true division (/) over integer division or int constants when generating tables.

Example fix

# before
emit_p = {'rainy': {'walk': 1, 'shop': 0}}  # ValueError

# after
emit_p = {'rainy': {'walk': 1.0, 'shop': 0.0}}
Defensive patterns

Strategy: validation

Validate before calling

def float_tables(table: dict) -> dict:
    return {k: {s: float(v) for s, v in row.items()} for k, row in table.items()}

Type guard

def float_valued(d: object) -> TypeGuard[dict[str, float]]:
    return isinstance(d, dict) and all(isinstance(v, float) for v in d.values())

Prevention

When it happens

Trigger: Passing emission_probabilities={'rainy': {'walk': 1}} (int 1 instead of 1.0); a probability table where any leaf is an int, string, or None; the doctest _validate_dict({'b': 4}, 'mock_name', float, True) reproduces it exactly.

Common situations: Writing probabilities as whole numbers (0 or 1) in hand-authored configs and forgetting the decimal point; JSON that deserializes 1.0 as int when the text is '1'; computed values from integer arithmetic instead of float division.

Related errors


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