Hi,
I have a dictionary storing many things... I would like to delete entries which have key of len < 3. But after I do the del statement, there are still lots of entries with len < 3, what happens?

for w in fdict.keys()[:]:
 if w.strip() in banset or len(w.strip()) < 3 or len(w.strip()) > 25:
  del fdict[w]
 elif isinstance(w, unicode):
  del fdict[w]

for w in fdict.keys():
 if len(w) < 3:
  print w, len(w)

some sample result of the print statement above:
ld 2
lg 2
lr 2
lv 2
ly 2
l? 2
l? 2
mi 2
mk 2
mt 2
np 2
nr 2
oc 2
oj 2
om 2
oo 2
ou 2
o? 2
p3 2
pl 2
pt 2
ri 2
rn 2
ro 2
sc 2
sf 2
sg 2
sh 2
sk 2
te 2
tt 2
u? 2
vg 2
vv 2
wk 2
x2 2
yu 2
zi 2
?? 2
?? 2
?? 2
?? 2
?& 2
?? 2
?? 2
? 1
? 1
? 1
? 1
? 1
? 1
? 1

Thanks in advance.

Raymond

Dani AI

Generated

Good — 's copy-based approach demonstrates the usual safe pattern and 's remark is the core point: mutating a dict while iterating it produces unreliable results. The iterator/iteration mechanism and the dictionary's internal state can get out of sync, so operations that delete entries during a single pass may skip, repeat, or leave items behind.

Why that happens (concise): modern Python exposes "views" of a mapping (see dictionary view objects). Iterating a live view while changing the mapping is not safe. The practical result depends on Python version and implementation details, so the only robust approach is to avoid mutating the dictionary in the same loop that walks it.

Working options (pick one that fits the codebase):

  • Rebuild a filtered dictionary (keeps logic simple and fast). If other code needs the same object, replace contents with clear() + update() so references remain valid.
  • Make a snapshot of the keys first, then delete from the original (e.g., collect keys to remove in a list, then loop over that list and delete).
  • If in-place deletion is required for memory reasons, first build the list of keys to delete and then remove them in a separate step.

Troubleshooting tips that helped other posters here: print repr(key) to reveal hidden characters, verify key types (bytes vs str/unicode), and normalize unicode if the data may contain combining marks or invisible codepoints. Note also that code using a unicode type check needs to be adjusted for Python 3 (use str or a compatibility layer).

These approaches avoid the iterator-vs-mutation pitfalls that produced the leftover short keys in the original run.

Recommended Answers

All 4 Replies

d1 = {'a': 1, 'bc': 2, 'def': 3, 'gh': 4, 'ijkl': 5}

# make shallow copy of d and process the copy
d2 = d1.copy()
for key in d1.keys():
    if len(key) < 3:
        del d2[key]

print(d1)  # {'a': 1, 'ijkl': 5, 'gh': 4, 'def': 3, 'bc': 2}
print(d2)  # {'ijkl': 5, 'def': 3}

It works! Thanks!
But why?

You don't want to change the dictionary you are iterating over.

You don't want to change the dictionary you are iterating over.

Thanks....

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.