Re: dict.keys() and dict.values() are always the same order, is it?

Discussion in 'Python' started by Cameron Simpson, Apr 20, 2010.

  1. On 20Apr2010 11:03, Menghan Zheng <> wrote:
    | 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()])
    | --> ?

    It is always true. At this URL:

    http://docs.python.org/library/stdtypes.html?highlight=values#dict.items

    it says:

    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()).

    BTW, I got to that particular piece of text by starting at the doco for
    the .values() method of "dict", which links to the .items() method.

    Cheers,
    --
    Cameron Simpson <> DoD#743
    http://www.cskk.ezoshosting.com/cs/

    I couldn't think of anything else to do with it, so I put it on the web.
    Cameron Simpson, Apr 20, 2010
    #1
    1. Advertising

  2. Cameron Simpson

    alex23 Guest

    Cameron Simpson <> 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.
    alex23, Apr 20, 2010
    #2
    1. Advertising

  3. On 19Apr2010 21:31, alex23 <> wrote:
    | Cameron Simpson <> 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 <> 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.
    - (rob derrick)
    Cameron Simpson, Apr 20, 2010
    #3
  4. Cameron Simpson

    John Yeung Guest

    On Apr 20, 1:23 am, Cameron Simpson <> wrote:
    > On 19Apr2010 21:31, alex23 <> wrote:
    > | Cameron Simpson <> 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
    John Yeung, Apr 20, 2010
    #4
  5. On Mon, 19 Apr 2010 23:47:06 -0700, John Yeung wrote:

    > On Apr 20, 1:23 am, Cameron Simpson <> wrote:
    >> On 19Apr2010 21:31, alex23 <> wrote: | Cameron Simpson
    >> <> 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
    Steven D'Aprano, Apr 20, 2010
    #5
  6. Cameron Simpson

    John Yeung Guest

    alex23 wrote:
    > > > > I stand corrected. Thanks Cameron.


    Cameron Simpson wrote:
    > > > Oh, I was all ready to say what you said, but decided
    > > > to check the docs myself first:)


    John Yeung wrote:
    > > 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! ;)


    Steven D'Aprano wrote:
    > It is a language feature that is guaranteed to be true
    > for every implementation of Python


    I never said it wasn't guaranteed to be true. I said it *feels*
    implementationy *to me*.

    > Defensive programming is good, but at the point that you
    > don't believe the promises that the language makes, how
    > can you trust anything?


    [Leave it to me to answer a rhetorical question.] I *believe* all the
    promises a language makes. I don't *trust* (more like depend on) all
    of them equally. If I (that is, me personally, with all my
    fallibility, insufficient knowledge of the language, etc.) feel that a
    promise is one that the language absolutely cannot afford to break, I
    will trust it not to break that promise. I won't need some document
    telling me "no, really and truly, we guarantee that". Other promises
    seem (to limited, fallible, subjective me) as though they would not be
    the end of the world if the language broke them. And so I am less
    likely to rely on those promises, even as I steadfastly stake my life
    on other promises.

    > 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?


    Not sure how often I'd want a list of value-item pairs, but anyway,
    you don't have to trust that d.values() and d.items() have the same
    order to use them individually, or to use the other stuff. I do trust
    that list comps work and that tuple packing and unpacking work. And I
    trust each individual key-value pair in a dictionary to have the
    correct key associated with the correct value... because that is the
    whole purpose of the dictionary. Without it, dictionaries are just
    useless. But d.items(), d.keys(), and d.values() could all use
    different orderings without rendering dictionaries (or zip) pointless,
    and certainly without destroying the usefulness of the language.

    > 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.


    That is your opinion, and it may well be the opinion of the Python
    community at large. Fine. The version that doesn't use divmod is, to
    me, short enough and easy enough to read. I can easily imagine
    someone spending enough time looking up the docs (even if only to type
    help(divmod)) that it would be a net gain of time to simply avoid
    divmod altogether and just type the code that comes naturally to them.

    > > 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 :)


    Well, maybe there are coders out there who find that snippet short
    enough and easy enough to read. Maybe they are comfortable typing it
    all the time and seeing it all over their code. But if *I* can't
    remember whether ints are automatically promoted to longs, then what
    *I* will continue to write is actually just

    result = long(a) + long(b)

    ;)

    John
    John Yeung, Apr 21, 2010
    #6
  7. Cameron Simpson

    alex23 Guest

    Steven D'Aprano <> wrote:
    > 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?


    Because .iteritems() is an atomic operation while the .values/.items
    approach is two independent calls. That the former binds the two
    together in its implementation makes sense, that two _independent_
    methods are bound feels far more like magic.
    alex23, Apr 21, 2010
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Menghan Zheng
    Replies:
    1
    Views:
    268
    alex23
    Apr 20, 2010
  2. Henrik Faber
    Replies:
    8
    Views:
    215
    Ethan Furman
    Jul 26, 2012
  3. Ethan Furman

    Python 3: dict & dict.keys()

    Ethan Furman, Jul 24, 2013, in forum: Python
    Replies:
    4
    Views:
    204
    Steven D'Aprano
    Jul 25, 2013
  4. Peter Otten

    Re: Python 3: dict & dict.keys()

    Peter Otten, Jul 24, 2013, in forum: Python
    Replies:
    1
    Views:
    91
    Neil Cerutti
    Jul 24, 2013
  5. Oscar Benjamin

    Re: Python 3: dict & dict.keys()

    Oscar Benjamin, Jul 24, 2013, in forum: Python
    Replies:
    0
    Views:
    101
    Oscar Benjamin
    Jul 24, 2013
Loading...

Share This Page