Adam Olsen wrote:
The latter is even the prefered form, since it only invokes a single dict lookup:
On 2/16/06, Delaney, Timothy (Tim) <tdelaney@avaya.com> wrote:
try: v = d[key] except: v = d[key] = value
Obviously this example could be changed to use default_factory, but I find it hard to believe the only use of that pattern is to set default keys.
I'd go further -- I doubt many cases where try:except KeyError: is used could be refactored to use default_factory -- default_factory can only be used to set default keys to something that can be determined sometime close to the time the dictionary is created, and that the default is not dependent on the context in which the key is fetched, and that default value will not cause unintended side effects if the dictionary leaks out of the code where it was initially used (like if the dictionary is returned to someone). Any default factory is more often an algorithmic detail than truly part of the nature of the dictionary itself. For instance, here is something I do often: try: value = cache[key] except KeyError: ... calculate value ... cache[key] = value Realistically, factoring "... calculate value ..." into a factory that calculates the value would be difficult, produce highly unreadable code, perform worse, and have more bugs. For simple factories like "list" and "dict" the factory works okay. For immutable values like 0 and None, the factory (lambda : 0 and lambda : None) is a wasteful way to create a default value (because storing the value in the dictionary is unnecessary). For non-trivial factories the whole thing falls apart, and one can just hope that no one will try to use this feature and will instead stick with the try:except KeyError: technique. -- Ian Bicking / ianb@colorstudy.com / http://blog.ianbicking.org