pandas-dev/pandas · error · TypeError

to_dict() only accepts initialized defaultdicts

Error message

to_dict() only accepts initialized defaultdicts

What it means

Raised by the to_dict helper when `into` is exactly the defaultdict *class* (collections.defaultdict) rather than an *instance* of it. to_dict needs a default_factory to construct a defaultdict, which only an instance (e.g. defaultdict(list)) carries. Passing the bare class is rejected so users do not silently get default_factory=None.

Solutions

  1. Pass an initialized defaultdict: ser.to_dict(into=defaultdict(list)).
  2. Pick the factory matching the value shape (list for grouped, int/float for counters).
  3. If you do not need defaults, use plain dict (the default).

Example fix

// before
out = df.groupby('k')['v'].apply(list).to_dict(into=defaultdict)
// after
from collections import defaultdict
out = df.groupby('k')['v'].apply(list).to_dict(into=defaultdict(list))
Defensive patterns

Strategy: validation

Validate before calling

from collections import defaultdict
if into is defaultdict:
    raise TypeError('pass an instance: defaultdict(list)')
out = ser.to_dict(into=into)

Type guard

def is_defaultdict_instance(x) -> bool:
    from collections import defaultdict
    return isinstance(x, defaultdict)

Prevention

When it happens

Trigger: ser.to_dict(into=defaultdict); ser.to_dict(into=collections.defaultdict).

Common situations: Copy-pasting defaultdict without instantiation; assuming the class itself is a valid mapping factory.

Related errors


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

Appendix: 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 3b7651241d)