Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is Python 3.3+ dict ordering not only undefined, but variable? [duplicate]

Tags:

python

django

I'm asking this question out of curiosity (specifically, insight into how python is working under the hood).

I am fully aware that the python dict object is unordered - you can put in a bunch of items, and print out some representation of the dict, and the ordering of the items in the representation will have no correspondence to the order that the items were entered.

What I'm curious about, however, is why the ordering changes from one execution of the code to the next?

I have a really simple python script that is printing a dict to the console. The dict looks like this (content is pretty irrelevant):

{
    'hello': 'hi',
    'goodbye': 'bye',
    'hahaha': 'lol',
}

Printing it to the console causes the items to not only be printed in a random order, but to be printed in a different order each time I run the program. Here's my question: Why is this the case?

NOTE: The python code is inside a django project (but I'm not using any django functionality in this case - just mentioning this in case it's somehow relevant).

like image 449
Gershom Maes Avatar asked Mar 14 '23 22:03

Gershom Maes


1 Answers

There is a note about this here: https://docs.python.org/3/reference/datamodel.html#object.__hash__

Here is the note:

Note: By default, the __hash__() values of str, bytes and datetime objects are “salted” with an unpredictable random value. Although they remain constant within an individual Python process, they are not predictable between repeated invocations of Python. This is intended to provide protection against a denial-of-service caused by carefully-chosen inputs that exploit the worst case performance of a dict insertion, O(n^2) complexity. See http://www.ocert.org/advisories/ocert-2011-003.html for details. Changing hash values affects the iteration order of dicts, sets and other mappings. Python has never made guarantees about this ordering (and it typically varies between 32-bit and 64-bit builds).

See also PYTHONHASHSEED.

Changed in version 3.3: Hash randomization is enabled by default.

like image 138
Riccati Avatar answered Mar 19 '23 19:03

Riccati