From: alex23 on 20 Apr 2010 00:31 Cameron Simpson <c...(a)zip.com.au> wrote: > If items(), keys(), values(), iteritems(), iterkeys(), and > itervalues() are called with no intervening modifications to the > dictionary, the lists will directly correspond. This allows the > creation of (value, key) pairs using zip(): pairs = zip(d.values(), > d.keys()). I stand corrected. Thanks Cameron.
From: Cameron Simpson on 20 Apr 2010 01:23 On 19Apr2010 21:31, alex23 <wuwei23(a)gmail.com> wrote: | Cameron Simpson <c...(a)zip.com.au> wrote: | > If items(), keys(), values(), iteritems(), iterkeys(), and | > itervalues() are called with no intervening modifications to the | > dictionary, the lists will directly correspond. This allows the | > creation of (value, key) pairs using zip(): pairs = zip(d.values(), | > d.keys()). | | I stand corrected. Thanks Cameron. Oh, I was all ready to say what you said, but decided to check the docs myself first:-) Cheers, -- Cameron Simpson <cs(a)zip.com.au> DoD#743 http://www.cskk.ezoshosting.com/cs/ I really don't like :-) symbols as well. I feel that if you can't see the pie coming, you deserve whipped cream up your nose. - robd(a)cherry.cray.com (rob derrick)
From: John Yeung on 20 Apr 2010 02:47 On Apr 20, 1:23 am, Cameron Simpson <c...(a)zip.com.au> wrote: > On 19Apr2010 21:31, alex23 <wuwe...(a)gmail.com> wrote: > | Cameron Simpson <c...(a)zip.com.au> wrote: > | > If items(), keys(), values(), iteritems(), iterkeys(), and > | > itervalues() are called with no intervening modifications to the > | > dictionary, the lists will directly correspond. This allows the > | > creation of (value, key) pairs using zip(): pairs = zip(d.values(), > | > d.keys()). > | > | I stand corrected. Thanks Cameron. > > Oh, I was all ready to say what you said, but decided to check the docs > myself first:-) I am not too comfortable relying on it. It feels fragile and "implementationy" to me, as I'm sure it does to many people (such as everyone in this thread so far! ;) I do trust the docs on this issue, but every so often I forget that I read this bit of the docs, and am once again left with an insecure feeling about it. All in all, the alternative idiom for flipping keys and values (provided in the docs a couple of sentences down from your quote) is short enough for my taste, easy enough for me to read, and never makes me wonder if I should check the docs just to be sure: pairs = [(v, k) for (k, v) in d.iteritems()] Personally, I have never encountered a situation where I thought "hmm... if only I could rely on pairwise ordering, that would make my code so much simpler!" I'm sure that's partly because I don't code enough, but I think it's also due to dictionaries just being pretty easy to use even without implicitly synchronized pairs. John
From: Steven D'Aprano on 20 Apr 2010 03:48 On Mon, 19 Apr 2010 23:47:06 -0700, John Yeung wrote: > On Apr 20, 1:23 am, Cameron Simpson <c...(a)zip.com.au> wrote: >> On 19Apr2010 21:31, alex23 <wuwe...(a)gmail.com> wrote: | Cameron Simpson >> <c...(a)zip.com.au> wrote: | > If items(), keys(), values(), >> iteritems(), iterkeys(), and | > itervalues() are called with no >> intervening modifications to the | > dictionary, the lists will >> directly correspond. This allows the | > creation of (value, key) >> pairs using zip(): pairs = zip(d.values(), | > d.keys()). >> | >> | I stand corrected. Thanks Cameron. >> >> Oh, I was all ready to say what you said, but decided to check the docs >> myself first:-) > > I am not too comfortable relying on it. It feels fragile and > "implementationy" to me, as I'm sure it does to many people (such as > everyone in this thread so far! ;) It is a language feature that is guaranteed to be true for every implementation of Python, as much of a promise as the guarantee that sorted([3,1,2]) will return [1,2,3] or that [1,2,3][42:142] will return [] rather than fail. It's not an implementation detail that implementations are free to change, it is a promised language feature. If it ever fails, that is a bug that needs to be reported. Defensive programming is good, but at the point that you don't believe the promises that the language makes, how can you trust anything? You suggested pairs = [(v, k) for (k, v) in d.iteritems()] as an alternative, but if you don't trust the language to behave correctly in this case: pairs = zip(d.values(), d.items()) what makes you think you can trust d.iteritems(), list comprehensions, or even tuple packing and unpacking? > I do trust the docs on this issue, > but every so often I forget that I read this bit of the docs, and am > once again left with an insecure feeling about it. *shrug* This is no different to any other little-used feature. I personally never remember whether divmod(a,b) returns (a//b, a%b) or the other way around, but that doesn't mean that the behaviour of divmod is implementation dependent, or that I'm justified in feeling insecure about it. One behaviour is promised, and anything else would be a bug. It would be a waste of time and code for me to write a//b, a%b just because I can't remember what divmod() does. > All in all, the > alternative idiom for flipping keys and values (provided in the docs a > couple of sentences down from your quote) is short enough for my taste, > easy enough for me to read, and never makes me wonder if I should check > the docs just to be sure: > > pairs = [(v, k) for (k, v) in d.iteritems()] Yes, and if you can't remember whether or not ints are automatically promoted to longs, you will continue writing this long after it became unnecessary: try: result = a + b except OverflowError: result = long(a) + long(b) and then other coders will laugh at you :) (But of course if you need to still support older versions of Python, then it isn't silly at all.) -- Steven
From: Dave Angel on 20 Apr 2010 04:13
Menghan Zheng wrote: > Hello! > > Is it assured the following statement is always True? > If it is always True, in which version, python2.x or python3.x? > > >>>> a = dict() >>>> > ... > >>>> assert(a.values == [a[k] for k in a.keys()]) >>>> > --> ? > > > Menghan Zheng > > No, it's never true. The assert statement has no return value, neither True nor False. But probably you're asking whether the assert statement will succeed quietly. Again, the answer is no. The first part of the expression is a built-in method, and the second part is a (possibly-empty) list. So it'll always throw an AssertionError. But probably you've got a typo, and meant to include the parentheses: assert(a.values() == [a[k] for k in a.keys()]) That, I believe, is guaranteed to not fire the assertion in 2.6. In 2.6, the docs say: "If items(), keys(), values(), iteritems(), iterkeys(), and itervalues() are called with no intervening modifications to the dictionary, the lists will directly correspond" In 3.x it should fire an assertion error, for any dictionary, because values() does not return a list, but an iterator for one. However, I don't have the docs for 3.x handy, I just tried it interactively to confirm my belief. DaveA |