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

2009-12-11 Thread Roy Hyunjin Han
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(, {1: set([1])})
Popping and updating in two steps: defaultdict(, {1: set([1])})

After initialization: defaultdict(, {1: set([1])})
Popping and updating in one step: defaultdict(, {})


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


inOneStepVSTwoSteps.py
Description: Binary data
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


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

2009-12-11 Thread Roy Hyunjin Han
On Fri, Dec 11, 2009 at 2:43 PM, MRAB  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(, {1: set([1])})
>>> Popping and updating in two steps: defaultdict(, {1:
>>> set([1])})
>>> 
>>> After initialization: defaultdict(, {1: set([1])})
>>> Popping and updating in one step: defaultdict(, {})
>>>
>>>
>>> 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.
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


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

2009-12-14 Thread Roy Hyunjin Han
On Fri, Dec 11, 2009 at 7:59 PM, Nick Coghlan  wrote:
> It follows the standard left-to-right evaluation order within an expression:
>
> ()
>
> (i.e. a function call always determines which function is going to be
> called before determining any arguments to be passed)
>
> Splitting it into two lines then clearly changes the evaluation order:
>
> temp = 
> (temp)
>
> I'm not sure what behaviour could be suggested as being more intuitive -
> the problem in this case arose due to both referencing and mutating the
> same object in a single statement, which is always going to be
> problematic from an ordering point of view, since it depends on subtle
> details of statement definitions that people often won't know. Better to
> split the mutation and the reference into separate statements so the
> intended order is clear regardless of how well the reader knows the
> subtleties of Python's evaluation order.
>
> Cheers,
> Nick.
>

Thanks for the explanation, Nick.  I understand what is happening now.
 y[1].update resolves to the update() method of the old set referenced
by y[1], but this set is then popped so that the update() manages to
change the old set, but not the new one that is returned by any
subsequent reference to y[1].  I suppose I will have to keep this in
two statements.  A similar thing happened with the SWIG extensions for
GDAL, in which one had to separate statements so that SWIG objects
were not destroyed prematurely, i.e. no more one-liners.
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] About adding a new iterator method called "shuffled"

2009-03-24 Thread Roy Hyunjin Han
I know that Python has iterator methods called "sorted" and "reversed" and
these are handy shortcuts.


Why not add a new iterator method called "shuffled"?

>>> for x in shuffled(range(5)):
>>>print x
>>> 3
>>> 1
>>> 2
>>> 0
>>> 4


Currently, a person has to do the following because random.shuffle() does
not return the actual shuffled list.  It is verbose.

>>> import random
>>> x = range(5)
>>> random.shuffle(x)
>>> for x in x:
>>> print x
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] What if replacing items in a dictionary returns the new dictionary?

2011-04-29 Thread Roy Hyunjin Han
It would be convenient if replacing items in a dictionary returns the
new dictionary, in a manner analogous to str.replace().  What do you
think?
::

# Current behavior
x = {'key1': 1}
x.update(key1=3) == None
x == {'key1': 3} # Original variable has changed

# Possible behavior
x = {'key1': 1}
x.replace(key1=3) == {'key1': 3}
x == {'key1': 1} # Original variable is unchanged
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] What if replacing items in a dictionary returns the new dictionary?

2011-04-29 Thread Roy Hyunjin Han
2011/4/29 R. David Murray :
> 2011/4/29 Roy Hyunjin Han :
>> It would be convenient if replacing items in a dictionary returns the
>> new dictionary, in a manner analogous to str.replace()
>
> This belongs on python-ideas, but the short answer is no.  The
> general language design principle (as I understand it) is that
> mutable object do not return themselves upon mutation, while
> immutable objects do return the new object.

Thanks for the responses.  Sorry for the mispost, I'll post things
like this on python-ideas from now on.

RHH
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] What if replacing items in a dictionary returns the new dictionary?

2011-04-29 Thread Roy Hyunjin Han
>   You can implement this in your own subclass of dict, no?

Yes, I just thought it would be convenient to have in the language
itself, but the responses to my post seem to indicate that [not
returning the updated object] is an intended language feature for
mutable types like dict or list.

class ReplaceableDict(dict):
def replace(self, **kw):
'Works for replacing string-based keys'
return dict(self.items() + kw.items())
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] What if replacing items in a dictionary returns the new dictionary?

2011-05-05 Thread Roy Hyunjin Han
>> 2011/4/29 Roy Hyunjin Han :
>> It would be convenient if replacing items in a dictionary returns the
>> new dictionary, in a manner analogous to str.replace().  What do you
>> think?
>>
>># Current behavior
>>x = {'key1': 1}
>>x.update(key1=3) == None
>>x == {'key1': 3} # Original variable has changed
>>
>># Possible behavior
>>x = {'key1': 1}
>>x.replace(key1=3) == {'key1': 3}
>>x == {'key1': 1} # Original variable is unchanged
>>
> 2011/5/5 Giuseppe Ottaviano :
> In general nothing stops you to use a proxy object that returns itself
> after each method call, something like
>
> class using(object):
>def __init__(self, obj):
>self._wrappee = obj
>
>def unwrap(self):
>return self._wrappee
>
>def __getattr__(self, attr):
>def wrapper(*args, **kwargs):
>getattr(self._wrappee, attr)(*args, **kwargs)
>return self
>return wrapper
>
>
> d = dict()
> print using(d).update(dict(a=1)).update(dict(b=2)).unwrap()
> # prints {'a': 1, 'b': 2}
> l = list()
> print using(l).append(1).append(2).unwrap()
> # prints [1, 2]

Cool!  I never thought of that.  That's a great snippet.

I'll forward this to the python-ideas list.  I don't think the
python-dev people want this discussion to continue on their mailing
list.
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com