[Python-Dev] Splitting something into two steps produces different behavior from doing it in one fell swoop in Python 2.6.2
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
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
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"
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?
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/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?
> 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/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