Does CPython guarantee that dict.keys are in the same order as dict.values?

Does CPython guarantee to dict.keys()

be in the same order as dict.values()

on an unmodified dict?

In other words, is it always true that:

list(d.items()) == list(zip(d.keys(), d.values()))

      

The docs say:

Keys and values ​​are listed in no particular order [...] If elements (), keys (), values ​​(), iteritems (), iterkeys (), and itervalues ​​() are called without intermediate changes in the dictionary, the lists will be directly match.

However, the CPython source code suggests otherwise. dict.items () implementation in dictobject.c file :

/* Preallocate the list of tuples, to avoid allocations during
 * the loop over the items, which could trigger GC, which
 * could resize the dict. :-(
 */

      

So, is it true that dict.keys()

also dict.values()

on an unchanged dict, the elements will always be returned in the same order? Even if the GC is working?

If this is true, does this only apply to CPython or just Python 2?

+3


source to share


1 answer


Yes, it is still true because dict.keys()

and dict.values()

do not need to allocate new objects. You are presented with a list object with references to existing key or value objects, respectively.

On the other hand, dict.items()

you need to create tuple objects to store key-value pairs. Hence this comment.



Note that running the GC itself does not change the size of the dictionary; dicitonaries only change when they run out of space for new keys. But starting a GC can invoke a handler __del__

that can add to the dictionary that can resize. So it is the ability to run other Python code that can change the dictionary, which is prevented here.

+2


source







All Articles