Sorry, doesn't the following make a copy? >>>> from collections import defaultdict as dd >>>> x = dd(int) >>>> x[1] = 'a' >>>> x > defaultdict(<type 'int'>, {1: 'a'}) >>>> dict(x) > {1: 'a'} > >
I was hoping not to do that -- e.g., actually reuse the same underlying data. Maybe dict(x), where x is a defaultdict is smart? I agree that a defaultdict is safe to pass to most routines, but I guess I could imagine that a try/except block is used in a bit of code where on the key exception (when the value is absent) populates the value with a random number. In that application, a defaultdict would have no random values. Besides a slightly different favor, does the following have applications not covered by defaultdict? m.setdefault('key', []).append(1) I think I am unclear on the difference between that and: m['key'] = m.get('key',[]).append(1) Except that the latter works for immutable values as well as containers. On Fri, Jul 30, 2010 at 8:19 AM, Steven D'Aprano <st...@remove-this-cybersource.com.au> wrote: > On Fri, 30 Jul 2010 07:59:52 -0400, wheres pythonmonks wrote: > >> Instead of defaultdict for hash of lists, I have seen something like: >> >> >> m={}; m.setdefault('key', []).append(1) >> >> Would this be preferred in some circumstances? > > Sure, why not? Whichever you prefer. > > setdefault() is a venerable old technique, dating back to Python 2.0, and > not a newcomer like defaultdict. > > >> Also, is there a way to upcast a defaultdict into a dict? > > "Upcast"? Surely it is downcasting. Or side-casting. Or type-casting. > Whatever. *wink* > > Whatever it is, the answer is Yes: > >>>> from collections import defaultdict as dd >>>> x = dd(int) >>>> x[1] = 'a' >>>> x > defaultdict(<type 'int'>, {1: 'a'}) >>>> dict(x) > {1: 'a'} > > > >> I have also heard some people use >> exceptions on dictionaries to catch key existence, so passing in a >> defaultdict (I guess) could be hazardous to health. Is this true? > > Yes, it is true that some people use exceptions on dicts to catch key > existence. The most common reason to do so is to catch the non-existence > of a key so you can add it: > > try: > mydict[x] = mydict[x] + 1 > except KeyError: > mydict[x] = 1 > > > If mydict is a defaultdict with the appropriate factory, then the change > is perfectly safe because mydict[x] will not raise an exception when x is > missing, but merely return 0, so it will continue to work as expected and > all is good. > > Of course, if you pass it an defaultdict with an *inappropriate* factory, > you'll get an error. So don't do that :) Seriously, you can't expect to > just randomly replace a variable with some arbitrarily different variable > and expect it to work. You need to know what the code is expecting, and > not break those expectations too badly. > > And now you have at least three ways of setting missing values in a dict. > And those wacky Perl people say that Python's motto is "only one way to > do it" :) > > > > -- > Steven > -- > http://mail.python.org/mailman/listinfo/python-list > -- http://mail.python.org/mailman/listinfo/python-list