From: alex23 on
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
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
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
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
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