Path: csiph.com!newsfeed.hal-mli.net!feeder3.hal-mli.net!newsfeed.hal-mli.net!feeder1.hal-mli.net!newsfeed.xs4all.nl!newsfeed3.news.xs4all.nl!xs4all!newsgate.cistron.nl!newsgate.news.xs4all.nl!post.news.xs4all.nl!not-for-mail Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.023 X-Spam-Evidence: '*H*': 0.95; '*S*': 0.00; 'python.': 0.02; 'argument': 0.05; 'exists.': 0.07; 'problem?': 0.07; 'method,': 0.09; 'def': 0.12; 'wrote': 0.14; 'callable': 0.16; 'contributors': 0.16; 'defaultdict': 0.16; 'dict': 0.16; 'setdefault': 0.16; 'skip:n 70': 0.16; 'subject:dictionaries': 0.16; "value',": 0.16; "{'a':": 0.16; 'wrote:': 0.18; 'seems': 0.21; '>>>': 0.22; 'appears': 0.22; 'separate': 0.22; 'exists': 0.24; 'second': 0.26; 'header:In-Reply-To:1': 0.27; 'function': 0.29; 'am,': 0.29; "doesn't": 0.30; 'primarily': 0.30; 'message- id:@mail.gmail.com': 0.30; 'getting': 0.31; "skip:' 10": 0.31; '>>>>': 0.31; 'josh': 0.31; 'overhead': 0.31; 'probably': 0.32; 'cases': 0.33; 'subject:with': 0.35; "can't": 0.35; 'problem.': 0.35; 'but': 0.35; 'received:google.com': 0.35; 'building': 0.35; 'there': 0.35; 'doing': 0.36; 'method': 0.36; 'list': 0.37; 'easily': 0.37; 'sometimes': 0.38; 'depends': 0.38; 'initially': 0.38; 'to:addr:python-list': 0.38; 'pm,': 0.38; 'to:addr:python.org': 0.39; 'even': 0.60; 'skip:u 10': 0.60; 'solve': 0.60; 'no.': 0.61; 'simple': 0.61; "you're": 0.61; 'situation': 0.65; 'side': 0.67; 'frank': 0.68; 'default': 0.69; 'behavior': 0.77; '2:02': 0.84; 'abc': 0.84; 'dict()': 0.84; 'dict,': 0.84; 'either:': 0.91; 'dirty': 0.93 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :content-type; bh=VxQFVhsb4OeDhzaprXly71dYesqn3gfinhVVYb5EJW4=; b=gqCPDqd8OWX/DSwqkbp/dlHbBBOZUsNMBg3ncZkQivSRzLFdRnWUgu82xWNvFqSL+l oWMJyvroJKhrTrqD4TRB7RLl9XAI0zCrzffzQkfvhni01rB2oABrLvaWiwIlXzPuzk2/ qOjCK7wCpjgi124JC8C+52AUqtvSCL+LGZkvlizV2/mNST5+mhr+T9Z1pKDrUIoL4xpX tHw5kOJIrpD0VeXVT2A5WMfDS/3buVfqutSRLPKKmyJf3tMFdcRfAFPE6IkHW/B6J1cI +s7oBxahYFhUJFoZs9fx9XJKxVxfud8iGTWfc1/e9tqGI0rqlrwbcsnIR0H3Hj6JWyc2 7/tw== X-Received: by 10.66.240.70 with SMTP id vy6mr2756315pac.80.1396943653399; Tue, 08 Apr 2014 00:54:13 -0700 (PDT) MIME-Version: 1.0 In-Reply-To: References: <534105ce$0$1365$4fafbaef@reader1.news.tin.it> <21ef5159-ad95-4d43-a2d6-7ecda941d978@googlegroups.com> From: Ian Kelly Date: Tue, 8 Apr 2014 01:53:33 -0600 Subject: Re: Keeping track of things with dictionaries To: Python Content-Type: text/plain; charset=ISO-8859-1 X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Newsgroups: comp.lang.python Message-ID: Lines: 56 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1396943661 news.xs4all.nl 2838 [2001:888:2000:d::a6]:45864 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:69840 On Tue, Apr 8, 2014 at 1:14 AM, Frank Millman wrote: > > "Chris Angelico" wrote in message > news:CAPTjJmqFBt2XX+BDfNHz0gaGOrDkhtpBzrR29DUWN36girzcSw@mail.gmail.com... >> On Tue, Apr 8, 2014 at 2:02 PM, Josh English >> wrote: >>> >>> Would dict.setdefault() solve this problem? Is there any advantage to >>> defaultdict over setdefault() >> >> That depends on whether calling Brand() unnecessarily is a problem. >> Using setdefault() is handy when you're working with a simple list or >> something, but if calling Brand() is costly, or (worse) if it has side >> effects that you don't want, then you need to use a defaultdict. >> > > It appears that when you use 'setdefault', the default is always evaluated, > even if the key exists. > >>>> def get_value(val): > ... print('getting value', val) > ... return val*2 > ... >>>> my_dict = {} >>>> my_dict.setdefault('a', get_value('xyz')) > getting value xyz > 'xyzxyz' >>>> my_dict.setdefault('a', get_value('abc')) > getting value abc > 'xyzxyz' >>>> my_dict > {'a': 'xyzxyz'} >>>> > > It seems odd. Is there a situation where this behaviour is useful? No. The default argument is evaluated because it must be evaluated before it can be passed into the method, just like any other function argument in Python. So why doesn't it take a callable instead of a value for its second argument? At a guess, because the method was probably added for efficiency, and the function call overhead might easily be slower than just doing a separate getitem and setitem. The reason setdefault exists I think is primarily because it was added before defaultdict. The contributors at SO can't seem to come up with any particularly good use cases either: http://stackoverflow.com/questions/3483520/use-cases-for-the-setdefault-dict-method One thing I will note as a disadvantage of defaultdict is that sometimes you only want the default value behavior while you're initially building the dict, and then you just want a normal dict with KeyErrors from then on. defaultdict doesn't do that; once constructed, it will always be a defaultdict. You can copy the data into a normal dict using the dict() constructor, but this feels dirty to me.