AttributeError: 'dict' / 'str' object has no attribute 'append' (tested fix)

AttributeError: 'dict' object has no attribute 'append' (or 'str', 'set') means you called a list method on something that isn't a list. We reproduced it on six types in Python 3.13 and tested the right replacement for each.

1. append is a list method

Only list (and collections.deque) have .append(). Calling it on anything else raises AttributeError with that type's name. We tried six types:

for label, obj in [("dict", {}), ("str", ""), ("set", set()), ("tuple", ()), ("dict_keys", {}.keys()), ("int", 0)]:
    try:
        obj.append(1)
    except AttributeError as e:
        print(f"{label:10} AttributeError: {e}")

Output:

dict       AttributeError: 'dict' object has no attribute 'append'
str        AttributeError: 'str' object has no attribute 'append'
set        AttributeError: 'set' object has no attribute 'append'
tuple      AttributeError: 'tuple' object has no attribute 'append'
dict_keys  AttributeError: 'dict_keys' object has no attribute 'append'
int        AttributeError: 'int' object has no attribute 'append'

2. dict: assign a key, update, or append to a list value

A dict has no single "end" to append to, so you add by key. If you want a list of values per key, store a list under the key and append to that:

d = {"a": 1}
d["b"] = 2                  # add one key
d.update({"c": 3, "d": 4})  # add several
groups = {}
groups.setdefault("x", []).append(1)   # append to a list stored under a key
groups.setdefault("x", []).append(2)
print(d)
print(groups)

Output:

{'a': 1, 'b': 2, 'c': 3, 'd': 4}
{'x': [1, 2]}

collections.defaultdict(list) does the same grouping without setdefault:

from collections import defaultdict
groups = defaultdict(list)
for k, v in [("x", 1), ("y", 2), ("x", 3)]:
    groups[k].append(v)
print(dict(groups))

Output:

{'x': [1, 3], 'y': [2]}

3. str and set: concatenate, or use add

Strings are immutable, so build a new one with +=, or collect pieces in a list and "".join() them at the end. Sets use .add():

s = "ab"
s += "c"                 # strings: concatenate and rebind
parts = ["a", "b"]; parts.append("c")
print(s, "".join(parts))
seen = set(); seen.add(1)  # sets use add, not append
print(seen)

Output:

abc abc
{1}

4. The usual cause: the name was rebound

If the variable started as a list, something reassigned it. The traceback points at the append line, not at the line that caused it:

results = []
for x in [1, 2]:
    results = str(x)      # bug: rebinds the list name to a str
    results.append(x)

Output:

Traceback (most recent call last):
  File "/tmp/ap/b5.py", line 4, in <module>
    results.append(x)
    ^^^^^^^^^^^^^^
AttributeError: 'str' object has no attribute 'append'

Look for an assignment to the same name inside the loop, or a function that returns a dict or string where you expected a list. json.load() returns a dict when the file's top level is {...}. Print type(x) just before the failing line. For the reverse mix-up, see 'list' object has no attribute 'split'.

Frequently asked questions

How do I append to a dictionary in Python?

Assign a key: d[key] = value, or d.update(other). To collect several values per key, use d.setdefault(key, []).append(v) or collections.defaultdict(list).

How do I fix 'str' object has no attribute 'append'?

Strings are immutable: use s += 'x', or collect pieces in a list and ''.join() them. If the name was a list earlier, find where it was reassigned to a str.

What do I use instead of append for a set?

set.add(x) for one item, set.update(iterable) for many.

Written with AI assistance. Measured on 2026-10-22 on Debian with Python 3.13.5: append on dict, str, set, tuple, dict_keys and int, the dict/setdefault/defaultdict fixes, str and set alternatives, and a rebound loop variable. Every block was run verbatim and its output pasted unedited. PlainHeaders is our extension; Python is free.