Items ordering in Python dictionary - python

I am in simple doubt... I created the following dictionary:
>>> alpha={'a': 10, 'b': 5, 'c': 11}
But, when I want to see the dictionary keys and values I got:
>>> alpha
{'a': 10, 'c': 11, 'b': 5}
See that the "b" and "c" has swapped their position. How can I make the position be the same of the moment that the dictionary was created?

Dictionaries are unordered containers - if you want to preserve order, you can use collections.OrderedDict (Python 2.7 or later), or use another container type which is naturally order-preserving.
Generally if you have an access pattern that cares about ordered retrieval then a dictionary is solving a problem you don't have (fast access to random elements), while giving you a new one.

Dictonaries are not guaranting sorting of keys. You can find this information in python docs: http://docs.python.org/tutorial/datastructures.html#dictionaries
You can always sort dictionary keys or use other, more specialized collection.

Related

Why do the Items in a Python ChainMap reverse order when converted to a Dictionary?

Why does converting a ChainMap to a dictionary reverse the order of the items?
Here is an example.
>>> d = [{'a': 1}, {'b': 2}, {'c': 3}]
>>> ChainMap(*d)
ChainMap({'a': 1}, {'b': 2}, {'c': 3})
>>> dict(ChainMap(*d))
{'c': 3, 'b': 2, 'a': 1}
I can write alternate code to combine the dictionaries that does not reverse.
But, I would like to understand why this reversal happens for ChainMap.
It seems it would be desirable to keep the order.
ChainMap documentation mentions
Note, the iteration order of a ChainMap() is determined by scanning the mappings last to first.
The only mention of why ChainMap does this seems to be the following
This gives the same ordering as a series of dict.update() calls starting with the last mapping
Meanwhile, dict maintains insertion order since a few versions ago
Dictionaries preserve insertion order. Note that updating a key does not affect the order. Keys added after deletion are inserted at the end.
Changed in version 3.7: Dictionary order is guaranteed to be insertion order. This behavior was an implementation detail of CPython from 3.6.
So when you call dict(ChainMap(*d)), it iterates over the ChainMap i.e. reverse of the order of *d and that becomes insertion order for the new dict.

Does dict.values() returns in an ordered sequence? [duplicate]

This question already has answers here:
Why is the order in dictionaries and sets arbitrary?
(5 answers)
Closed 5 years ago.
dict_mark = {'Wang': 'C', 'Li': 'B', 'Ma': 'A'}
s = ''
for c in dict_mark.values():
s += c
print(s)
dictionary is unordered,so why does dict_mark.values() always return this value sequence like 'C' 'B' 'A'?
Why not 'B' 'A' 'C' or 'A' 'B' 'C'?
Unordered dos not mean not deterministic.
From the python 2.x docs:
If items(), keys(), values(), iteritems(), iterkeys(), and
itervalues() are called with no intervening modifications to the
dictionary, the lists will directly correspond.
In python 3.x docs:
Keys and values are iterated over in an arbitrary order which is non-random, varies across Python implementations, and depends on the dictionary’s history of insertions and deletions.
Thus, the sequence returned is always the same until you modify the dictionary. You just can't make assumptions on the objects being sorted in it.
Have a look at this question and the answers to it where they discuss about why (and how) in python 3.6+ dicts are actually ordered.
Since Python 3.6, dict keywords are ordered: https://mail.python.org/pipermail/python-dev/2016-September/146327.html
dict stores it's data in a hashtable data structure. So how does hashtable works?
On a nutshell: let's say the dict is initalized to 8 slots array-like object. When you add a new key-value pair to the dict, it hashes the key using a function that returns the slot the key will reside. This isn't deterministic since the slot may be already taken; so you need to re-evaluate and look for another slot.
That's why the order you retrieve values from dict.values() changes depend on the data in it. That's why it is called unordered.
For example, consider this simple dict:
>>> d = {'a': 1, 'aa': 2}
>>> d
{'a': 1, 'aa': 2}
>>> d = {'aa': 1, 'a': 2}
>>> d
{'aa': 1, 'a': 2}
If I change the order of the keys, it also appears different when I print the dict key-value pairs. But look what happens if I use different key
>>> d = {'b': 1, 'a': 2}
>>> d
{'a': 2, 'b': 1}
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.items().
The dictionary is stored as a hash table. In versions of Python prior to 3.6 iteration is done in the order they appear in the hash table, so that means the order you get depends on the hash value of each key. It also can vary based on the order of insertion and deletion when there have been hash conflicts.
In Python 2.x the hash value for a string is a fixed value, so while it might change between Python versions you will always see the same order for a given dictionary and a fixed set of actions on the dictionary.
In some versions of Python 3, the hash value for a string has random factor, so different runs will give a different result. In Python 3.6 the iteration order no longer depends on the hash key so you will again get a fixed order which will relate to the order of insertion (but there's no guarantee that it won't change again in the future).
$ python2.7 /tmp/t.py
ACB
$ python2.7 /tmp/t.py
ACB
$ python3.5 /tmp/t.py
BCA
$ python3.5 /tmp/t.py
ABC
$ python3.5 /tmp/t.py
CBA
It depends on several things in python how dict is ordered. You shouldn't think about it, since ordering in dict doesn't matter.

python-3.6 printing set expression not in order

There is one question about Python3.6. It's about the output of Set expressions. I do not know why the code below does not appear in order:
a = {i*2 for i in range(1, 5)}
print(a)
I expect {2, 4, 6, 8} but the output is {8, 2, 4, 6}
Why it is not in order?
If you take a look at the documentation; the first sentence of the set documentation is:
A set object is an unordered collection of distinct hashable objects.
So the order of the elements in the set is for all practical purposes random. Even in python-3.6.
1here is the example in python, elements of the set doesn't arrange in order i.e elements are arrange in random
Python sets are not ordered, they only contain elements. If you need your data structure to have a certain order, maybe consider an OrderedDict.

Sorting a dictionary by key in increasing order without using external libraries

I am trying to produce a dictionary that is the copy of another dictionary but with its keys sorted in increasing order. So far I have the following:
x = {89:1, 2:3, 3:1}
# produces x with its keys sorted in increasing order
# Example: sort(x) => {2:3, 3:1, 89:1}
def sort(x):
y = {}
for key in sorted(x):
y[key] = x[key]
print(y)
return y
Console output:
=>{2: 3}
=>{2: 3, 3: 1}
=>{89: 1, 2: 3, 3: 1}
=>{89: 1, 2: 3, 3: 1}
=>{89: 1, 2: 3, 3: 1} (the return statement)
The function seems to work fine for the first two keys (2 and 3) but then it breaks down when the last key is reached (89) and the function just spits out its input.
Why does the function work for the first two items but not for the last one? I don't think there is an aliasing problem here and I can't think of a clear reason for why this doesn't work.
I have researched this topic but none of the answers seem to reflect what I am looking for. I am planning to make this function work without the use of external libraries.
Any suggestions?
In python, dictionaries are not implemented with binary search trees. Actually if you check in the official documentation the explain:
It is best to think of a dictionary as an unordered set of key: value pairs, with the requirement that the keys are unique (within one dictionary).
Do not expect to see the elements on the dictionary sorted.
{key:a[key] for key in sorted(a.keys())} would be a more "Pythonic" way, BUT dictionaries have no order to them.
You could look at OrderedDict in collections.
from collections import OrderedDict
OrderedDict(sorted(x.items()))
Edited according to comments

The keys of a dictionary are not in the order when they are added?

>>> d={}
>>> d['c']=3
>>> d['b']=2
>>> d['a']=1
>>> d
{'a': 1, 'c': 3, 'b': 2}
>>> d.keys()
['a', 'c', 'b']
Are the keys in a dictionary not ordered in the same order they are added into the dictionary?
What order are they in?
What shall I do if I want to have the keys of a dictionary in the order that they are added into the dictionary?
Thanks.
dict is an unordered data structure. Keys will come out in some order when you iterate over them, but this may bear little resemblance to the order in which they were added. In return, you get O(1) lookup.
Use collections.OrderedDict if you need to retain the order.
Python dictionaries don't preserve order, and you cannot count on any particular order. Dictionary is a store for values where, by design, values are to be referred to by their keys – and not by a particular "slot" in which they are.
If you need to preserve order of added elements, use lists where a "slot" is referred to by an index, e.g. myList[3]. If you need to have 2 values coupled together (corresponding a "key" and a "value" as in your example), use a list of tuples.

Categories