2

Dictionaries in python are ordered since Python 3.6

From - https://stackoverflow.com/a/39980744/4647107

Are dictionaries ordered in Python 3.6+?

They are insertion ordered. As of Python 3.6, for the CPython implementation of Python, dictionaries remember the order of items inserted. This is considered an implementation detail in Python 3.6; you need to use OrderedDict if you want insertion ordering that's guaranteed across other implementations of Python.

As of Python 3.7, this is no longer an implementation detail and instead becomes a language feature. From a python-dev message by GvR:

Make it so. "Dict keeps insertion order" is the ruling. Thanks!

This simply means that you can depend on it. Other implementations of Python must also offer an insertion ordered dictionary if they wish to be a conforming implementation of Python 3.7.

Is there a way to implement an unordered dictionary in python now?

Pratyush Das
  • 460
  • 7
  • 24
  • 1
    _Is there a way to implement an unordered dictionary_ Sure - write your own. – John Gordon Feb 24 '19 at 06:03
  • any particular reason? you could mimic unordered behaviour by using `random.shuffle` on the keys and accessing them if you *really* wanted to. – Paritosh Singh Feb 24 '19 at 06:04
  • How would you tell the difference? The old dict implementation was entirely capable of returning items in insertion order, just by random accident. – jasonharper Feb 24 '19 at 06:04
  • @ParitoshSingh that might get cumbersome when storing a lot of keys in the dict. – Pratyush Das Feb 24 '19 at 06:22
  • 1
    @jasonharper I do not want the dict to remember the insertion order. I do not care if one of the many possible orders returned by the dict is the order in which the keys were inserted. – Pratyush Das Feb 24 '19 at 06:23
  • 1
    Why do you want that though? – Paritosh Singh Feb 24 '19 at 06:24
  • 1
    I don't see the point of this. The general use case for dictionaries is O(1) lookup. Ordering only makes a difference in iteration, and it's generally convenient for that to be consistent. What are you actually trying to do? – TigerhawkT3 Feb 24 '19 at 07:06
  • I guess that the OP's focus is on the non-functional specifications: Does the ordering, when it is not used, nonetheless impact performance, energy consumption, memory footprint, application security? – Bernhard Bodenstorfer Mar 03 '21 at 15:01

3 Answers3

2

You can fake it:

>>> import random
>>> d={'a':[1,2,3],'b':[4,5,6],'c':[7,8,9]}
>>> items=list(d.items())
>>> random.shuffle(items)
>>> dict(items)
{'c': [7, 8, 9], 'b': [4, 5, 6], 'a': [1, 2, 3]}
>>> 
U13-Forward
  • 69,221
  • 14
  • 89
  • 114
  • 1
    Is there a chance that random shuffling the key, value pairs might get cumbersome if the number of keys in the dict is sufficiently large? – Pratyush Das Feb 24 '19 at 06:24
  • @PratyushDas I don't think so – U13-Forward Feb 24 '19 at 06:27
  • I suspect the purpose of the question was less about wanting a non-predictable (random) order, but more about wanting a predictable and consistent order (i.e. the original behavior of sorting by keys) regardless of insertion order. – JGC Dec 11 '20 at 17:03
2

As a few people have mentioned it would help to understand why you would like an unordered dict. Personally I was looking for an unordered dict because I was working with OrderedDicts, and their behavior meant that I couldn't directly compare them using ==. For example:

In [1]: from collections import OrderedDict
In [2]: dict_1 = OrderedDict([('a', 0), ('b', 1), ('c', 2)])
In [3]: dict_2 = OrderedDict([('c', 2), ('b', 1), ('a', 0)])
In [4]: dict_1 == dict_2
Out[4]: False

A simple solution to this is to turn the OrderedDict back into a dict.

In [5]: dict(dict_1) == dict(dict_2)
Out[5]: True
JGC
  • 5,725
  • 1
  • 32
  • 30
  • 1
    Note that calling `sorted` on a dict produces a sorted _list_ of the dictionary's keys, not a sorted copy of the dictionary. The dictionary itself remains unordered. Also, both dict literals and the dict constructor order the initial elements from left to right, while dict comprehensions insert in their iteration order. The two dictionaries created in the answer using dict comprehensions are not equal because they have different keys-value pairs, because they were constructed by enumerating different lists: `dict_1 == {'a': 0, 'b': 1, 'c': 2}` and `dict_2 == {'c': 0, 'b': 1, 'a': 2}`. – jirassimok Jun 02 '21 at 22:56
  • 1
    [jirassimok](https://stackoverflow.com/users/7389264/jirassimok), thank you, you're absolutely right. I re-read my post and realized that I had made some mistakes that lead to incorrect assumptions. I have completely re-written my answer in light of this. – JGC Jun 03 '21 at 17:03
0

Might be too late to answer but here's what I used,

class UnorderedDict:
    def __setitem__(self, key, value):
        setattr(self, key, value)
    def __getitem__(self, key):
        return getattr(self, key)
test = UnorderedDict()
test["key"] = "yay"
print(test["key"])

It sets and gets attribute, this doesn't have any order afaik.

aph
  • 225
  • 3
  • 12