[Python-Dev] Splitting something into two steps produces different behavior from doing it in one fell swoop in Python 2.6.2

Roy Hyunjin Han starsareblueandfaraway at gmail.com
Fri Dec 11 21:52:38 CET 2009


On Fri, Dec 11, 2009 at 2:43 PM, MRAB <python at mrabarnett.plus.com> wrote:
> John Arbash Meinel wrote:
>>
>> Roy Hyunjin Han wrote:
>>>
>>> While debugging a network algorithm in Python 2.6.2, I encountered
>>> some strange behavior and was wondering whether it has to do with some
>>> sort of code optimization that Python does behind the scenes.
>>>
>>>
>>> ************
>>> After initialization: defaultdict(<type 'set'>, {1: set([1])})
>>> Popping and updating in two steps: defaultdict(<type 'set'>, {1:
>>> set([1])})
>>> ************
>>> After initialization: defaultdict(<type 'set'>, {1: set([1])})
>>> Popping and updating in one step: defaultdict(<type 'set'>, {})
>>>
>>>
>>> import collections
>>> print '************'
>>> x = collections.defaultdict(set)
>>> x[1].update([1])
>>> print 'After initialization: %s' % x
>>> items = x.pop(1)
>>> x[1].update(items)
>>> print 'Popping and updating in two steps: %s' % x
>>> print '************'
>>> y = collections.defaultdict(set)
>>> y[1].update([1])
>>> print 'After initialization: %s' % y
>>> y[1].update(y.pop(1))
>>> print 'Popping and updating in one step: %s' % y
>>>
>>
>> y[1].update(y.pop(1))
>>
>> is going to be evaluating y[1] before it evaluates y.pop(1).
>> Which means that it has the original set returned, which is then removed
>> by y.pop, and updated.
>>
>> You probably get the same behavior without using a defaultdict:
>>  y.setdefault(1, set()).update(y.pop(1))
>>  ^^^^^^^^^^^^^^^^^^^^^^- evaluated first
>>
>>
>> Oh and I should probably give the standard: "This list is for the
>> development *of* python, not development *with* python."
>>
> To me the question was whether Python was behaving correctly; the
> behaviour was more subtle than the legendary mutable default argument.

Thanks, John and MRAB.  I was pointing it out on this list because I
felt like it was counterintuitive and that the result should be the
same whether the developer decides to do it in two steps or in one
step.


More information about the Python-Dev mailing list