> However, "explicit is better than implicit", so self.nodes[n2] = list() is IMO much better.

@schlamar That has different behavior. We're not guaranteed that n2 has no successors.
The explicit version of this line would be:

    if n2 not in self.nodes[n2]: self.nodes[n2] = self.nodes.default_factory()

Which is, of course, the behavior of defaultdict itself, except with worse performance.
If you still like this better than it is currently written, I will change it.