Python2转Python3:defaultdict结合count迭代器报错求助
Got it, let's break this down and fix it for Python 3!
First, let's understand why your modified code throws that error:
fmap = defaultdict(next(count(1))) TypeError: first argument must be callable or None
When you write next(count(1)), you're immediately executing the next() call, which returns the integer 1—not a callable function/method. defaultdict requires its first argument to be something it can call every time it needs to generate a new default value, so passing a plain integer causes the type error.
Your original Python 2 code defaultdict(count(1).next) worked because it passed the .next() method of the counter iterator directly to defaultdict. Every time a new default value was needed, that method would be called to get the next incrementing number (1, 2, 3...).
The Fix for Python 3
You need to wrap the next() call in a reusable callable, while keeping the same counter instance so it increments properly. Here's the correct approach:
from collections import defaultdict from itertools import count # First create a persistent counter iterator counter = count(1) # Use a lambda to wrap next(counter) as a callable for defaultdict fmap = defaultdict(lambda: next(counter))
How This Works
- We first instantiate a single
count(1)iterator so it maintains its state across calls. - The lambda acts as a callable wrapper: every time
fmapencounters a new key, it runsnext(counter)to get the next incrementing value.
Test it out to confirm:
print(fmap["x"]) # Outputs 1 print(fmap["y"]) # Outputs 2 print(fmap["z"]) # Outputs 3
⚠️ Don't make the mistake of writing defaultdict(lambda: next(count(1)))—that would create a new count(1) iterator every time, so you'd always get 1 as the default value, which isn't what the original code intended.
内容的提问来源于stack exchange,提问作者Natalie Shapira

