pandas-dev/pandas · error · TypeError

to_dict() only accepts initialized defaultdicts

Error message

to_dict() only accepts initialized defaultdicts

What it means

Raised by standardize_mapping (pandas/core/common.py:430) when the `defaultdict` class itself (uninitialized) is passed as `into` to to_dict. defaultdict needs a default_factory to be useful; passing the bare class leaves the factory undefined, so pandas requires an initialized instance like defaultdict(list).

Source

Thrown at pandas/core/common.py:430

    Returns
    -------
    mapping : a collections.abc.Mapping subclass or other constructor
        a callable object that can accept an iterator to create
        the desired Mapping.

    See Also
    --------
    DataFrame.to_dict
    Series.to_dict
    """
    if not inspect.isclass(into):
        if isinstance(into, defaultdict):
            return partial(defaultdict, into.default_factory)
        into = type(into)
    if not issubclass(into, abc.Mapping):
        raise TypeError(f"unsupported type: {into}")
    if into == defaultdict:
        raise TypeError("to_dict() only accepts initialized defaultdicts")
    return into


@overload
def random_state(state: np.random.Generator) -> np.random.Generator: ...


@overload
def random_state(
    state: int | np.ndarray | np.random.BitGenerator | np.random.RandomState | None,
) -> np.random.RandomState: ...


def random_state(
    state: RandomState | None = None,
) -> np.random.RandomState | np.random.Generator:
    """
    Helper function for processing random_state arguments.

View on GitHub (pinned to 71959b8cb9)

Solutions

  1. Pass an initialized defaultdict: `into=collections.defaultdict(list)` (or dict, set, etc. as factory).
  2. If you don't need defaulting behavior, use `into=dict`.
  3. If you only know the factory at runtime, construct dynamically: `into=collections.defaultdict(factory)`.

Example fix

# before
from collections import defaultdict
df.to_dict(into=defaultdict)

# after
from collections import defaultdict
df.to_dict(into=defaultdict(list))
Defensive patterns

Strategy: validation

Validate before calling

from collections import defaultdict

def validate_defaultdict(into):
    if into is defaultdict:
        raise TypeError('Pass an initialized defaultdict, e.g. defaultdict(list)')
    return into

Type guard

from collections import defaultdict

def is_initialized_defaultdict(obj) -> bool:
    return isinstance(obj, defaultdict) and obj.default_factory is not None

Try / catch

try:
    result = df.to_dict(into=into)
except TypeError as e:
    if 'initialized defaultdicts' in str(e):
        from collections import defaultdict
        result = df.to_dict(into=defaultdict(list))
    else:
        raise

Prevention

When it happens

Trigger: `df.to_dict(into=collections.defaultdict)` (the class, no factory) vs the correct `df.to_dict(into=collections.defaultdict(list))`. Also `into=defaultdict` imported bare.

Common situations: Forgetting that defaultdict requires a factory argument; copy-pasting `defaultdict` as a type rather than constructing an instance.

Related errors


AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07). Data as JSON: /api/errors/eb1e9978fa7a66e7. Report an issue: GitHub.