Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What ordering does dict.keys() and dict.values() guarantee? [duplicate]

This question arises from this answer where one user uses d.keys() and d.values() separately to initialise a dataframe.

It's common knowledge that dictionaries in python versions under 3.6 are not ordered.

Consider a generic dictionary of the form:

d = {k1 : v1, k2 : v2, k3 : v3}

Where the keys k* are any hashable objects, and the values v* being any object. Of course, order cannot be guaranteed, but what about the order of d.keys() and d.values()?

Python 2.x

Both d.keys() and d.values() return lists. Say, .keys() returns d's keys in the order [k2, k1, k3]. Is it now always guaranteed that d.values() returns the same relative ordering as [v2, v1, v3]? Furthermore, does the ordering remain the same no matter how many times these functions are called?

Python 3.x (<3.6)

I'm not 100% sure, but I believe that .keys and .values do not guarantee any ordering at all here because they are set-like structures, thus having no order by definition and enabling you to perform set-like operations on them. But I'd still be interested to know if there is any sort of relative ordering between the two calls in this instance. I'm guessing not. I'd appreciate if someone could affirm or correct me.

like image 638
cs95 Avatar asked Nov 08 '17 05:11

cs95


People also ask

Are dict keys and dict values in the same order?

Yes, what you observed is indeed a guaranteed property — keys() , values() and items() return lists in congruent order if the dict is not altered.

Does dict values () return in order?

values() changes depend on the data in it. That's why it is called unordered. Althought I stated the 'b' key first, it was allocated after 'a' . However, once the dict is set, it will always return the same order when called dict.

Does dict keys () return in order?

Answer. No, there is no guaranteed order for the list of keys returned by the keys() function.

Does dict values keep order?

Standard dict objects preserve order in the reference (CPython) implementations of Python 3.5 and 3.6, and this order-preserving property is becoming a language feature in Python 3.7.


Video Answer


1 Answers

The general rules:

  1. Before talking about what is guaranteed and what isn't, even if some ordering seems to be "guaranteed", it isn't. You should not rely on it. It is considered bad practice, and could lead to nasty bugs.
  2. d.keys(), d.values(), and d.items() all return the elements in a respective order. The order should be treated as arbitrary (no assumptions should be made about it). (docs)
  3. consecutive calls to d.keys(), d.values(), and d.items() are "stable", in the sense they are guaranteed to preserve the order of previous calls (assuming no insertion/deletion happens between the calls).
  4. Since CPython's V3.6, dict has been reimplemented, and it now preserves insertion order. This was not the goal of the change, but a side effect, and it is NOT part of the python spec, only a detail of the CPython implementation. See point #1 above: relying on this is bad practice and should not be done. Anyways, you should avoid writing CPython-specific code.
  5. In Python2, order is deterministic (i.e. creating a dict twice in the same way will result with the same order). In Python <3.6, it is no longer deterministic, so you can't rely on that either (I'm not sure if this non-determinism is part of the spec or just a CPython implementation detail).

EDIT: added point #5, thanks to @AndyHayden's comment.

like image 186
shx2 Avatar answered Sep 28 '22 00:09

shx2