Order of keys in dictionaries in old versions of Python - python

Code:
d = {'a': 0, 'b': 1, 'c': 2}
l = d.keys()
print l
This prints ['a', 'c', 'b']. I'm unsure of how the method keys() determines the order of the keywords within l. However, I'd like to be able to retrive the keywords in the "proper" order. The proper order of course would create the list ['a', 'b', 'c'].

Python 3.7+
In Python 3.7.0 the insertion-order preservation nature of dict objects has been declared to be an official part of the Python language spec. Therefore, you can depend on it.
Python 3.6 (CPython)
As of Python 3.6, for the CPython implementation of Python, dictionaries maintain insertion order by default. This is considered an implementation detail though; you should still use collections.OrderedDict if you want insertion ordering that's guaranteed across other implementations of Python.
Python >=2.7 and <3.6
Use the collections.OrderedDict class when you need a dict that
remembers the order of items inserted.

You could use OrderedDict (requires Python 2.7) or higher.
Also, note that OrderedDict({'a': 1, 'b':2, 'c':3}) won't work since the dict you create with {...} has already forgotten the order of the elements. Instead, you want to use OrderedDict([('a', 1), ('b', 2), ('c', 3)]).
As mentioned in the documentation, for versions lower than Python 2.7, you can use this recipe.

>>> print sorted(d.keys())
['a', 'b', 'c']
Use the sorted function, which sorts the iterable passed in.
The .keys() method returns the keys in an arbitrary order.

From http://docs.python.org/tutorial/datastructures.html:
"The keys() method of a dictionary object returns a list of all the keys used in the dictionary, in arbitrary order (if you want it sorted, just apply the sorted() function to it)."

Just sort the list when you want to use it.
l = sorted(d.keys())

Although the order does not matter as the dictionary is hashmap. It depends on the order how it is pushed in:
s = 'abbc'
a = 'cbab'
def load_dict(s):
dict_tmp = {}
for ch in s:
if ch in dict_tmp.keys():
dict_tmp[ch]+=1
else:
dict_tmp[ch] = 1
return dict_tmp
dict_a = load_dict(a)
dict_s = load_dict(s)
print('for string %s, the keys are %s'%(s, dict_s.keys()))
print('for string %s, the keys are %s'%(a, dict_a.keys()))
output:
for string abbc, the keys are dict_keys(['a', 'b', 'c'])
for string cbab, the keys are dict_keys(['c', 'b', 'a'])

Related

Dict with sorted keys

Is there a built-in dict subclass in the Python standard library that keeps the keys in their order, so that items() or keys() return in the order of keys (I mean not the order of insertion (which OrderedDict would do), but the actual relative order of the keys to each other). The equivalent for arrays would be a priority queue, but I haven't heard of anything like this for dicts.
Noticed that I missed the part of the question that says "keep it sorted". Some mentions from comments on the original question point to grantjenks.com/docs/sortedcontainers/sorteddict.html that looks good.
If there is no need to "keep sorted" the following helps.
This will do the trick:
sorted(my_dict.items())
For example:
for key, value in sorted(my_dict.items()):
print(key)
** update based on the comments **
If you want to return a dictionary with the sorted order (and guarantee it):
sorted_dict = OrderedDict(sorted(my_dict.items()))
By default, no dict keys are not sorted because of the properties of a dict object.
Try:
a = {'c': 'd', 'a': 'b', 'e': 'f'}
print(a.keys())
print(sorted(a.keys()))
And you can get the keys as a sorted list.

Python Dictionary Key Order With Comprehensions

I'm messing around with dictionaries for the first time and something's coming up that's confusing me. Using two lists to create a new dictionary, the order of the list terms for the key part seems to be wrong. Here's my code:
list1 = ["a", "b", "c", "d"]
list2 = [5,3,7,3]
newDict = {list1[c]: number for c, number in enumerate(list2)}
print(newDict)
This gives me the following:
{'a': 5, 'd': 3, 'c': 7, 'b': 3}
Why is this happening? Surely the 'c' value getting terms from the list is going from 0 and upwards, so why isn't it creating the dictionary with the letters in the same order?
Thanks.
For purposes of efficiency, traditional python dictionaries are unordered. If you need order, then you need OrderedDict:
>>> from collections import OrderedDict
>>> newDict = OrderedDict((list1[c], number) for c, number in enumerate(list2))
>>> print(newDict)
OrderedDict([('a', 5), ('b', 3), ('c', 7), ('d', 3)])
In Python 3.7, ordinary python dictionaries, implemented using a new algorithm, will be ordered. Until then, if you need order, use OrderedDict.
Python dictionaries don't preserve their order, but there's another data type that does: OrderedDict, from the collections module.
Dictionaries are unordered. In fact, if you run your program on a different computer, you might get a different key ordering. This is an intentional feature of the built-in dictionary in python.
To understand why, take a look at this stackoverflow question.
As of Python 3.7, dictionaries are insertion ordered.
See this stackoverflow discussion Are dictionaries ordered in Python 3.6+?

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.

Join function and dictionary in python [duplicate]

Code:
d = {'a': 0, 'b': 1, 'c': 2}
l = d.keys()
print l
This prints ['a', 'c', 'b']. I'm unsure of how the method keys() determines the order of the keywords within l. However, I'd like to be able to retrive the keywords in the "proper" order. The proper order of course would create the list ['a', 'b', 'c'].
Python 3.7+
In Python 3.7.0 the insertion-order preservation nature of dict objects has been declared to be an official part of the Python language spec. Therefore, you can depend on it.
Python 3.6 (CPython)
As of Python 3.6, for the CPython implementation of Python, dictionaries maintain insertion order by default. This is considered an implementation detail though; you should still use collections.OrderedDict if you want insertion ordering that's guaranteed across other implementations of Python.
Python >=2.7 and <3.6
Use the collections.OrderedDict class when you need a dict that
remembers the order of items inserted.
You could use OrderedDict (requires Python 2.7) or higher.
Also, note that OrderedDict({'a': 1, 'b':2, 'c':3}) won't work since the dict you create with {...} has already forgotten the order of the elements. Instead, you want to use OrderedDict([('a', 1), ('b', 2), ('c', 3)]).
As mentioned in the documentation, for versions lower than Python 2.7, you can use this recipe.
>>> print sorted(d.keys())
['a', 'b', 'c']
Use the sorted function, which sorts the iterable passed in.
The .keys() method returns the keys in an arbitrary order.
From http://docs.python.org/tutorial/datastructures.html:
"The keys() method of a dictionary object returns a list of all the keys used in the dictionary, in arbitrary order (if you want it sorted, just apply the sorted() function to it)."
Just sort the list when you want to use it.
l = sorted(d.keys())
Although the order does not matter as the dictionary is hashmap. It depends on the order how it is pushed in:
s = 'abbc'
a = 'cbab'
def load_dict(s):
dict_tmp = {}
for ch in s:
if ch in dict_tmp.keys():
dict_tmp[ch]+=1
else:
dict_tmp[ch] = 1
return dict_tmp
dict_a = load_dict(a)
dict_s = load_dict(s)
print('for string %s, the keys are %s'%(s, dict_s.keys()))
print('for string %s, the keys are %s'%(a, dict_a.keys()))
output:
for string abbc, the keys are dict_keys(['a', 'b', 'c'])
for string cbab, the keys are dict_keys(['c', 'b', 'a'])

How to print unsorted dictionary in python?

I have this dict in python;
d={}
d['b']='beta'
d['g']='gamma'
d['a']='alpha'
when i print the dict;
for k,v in d.items():
print k
i get this;
a
b
g
it seems like python sorts the dict automatically! how can i get the original unsorted list?
Gath
Dicts don't work like that:
CPython implementation detail: Keys and values are listed in an arbitrary order which is non-random, varies across Python implementations, and depends on the dictionary’s history of insertions and deletions.
You could use a list with 2-tuples instead:
d = [('b', 'beta'), ('g', 'gamma'), ('a', 'alpha')]
A similar but better solution is outlined in Wayne's answer.
As has been mentioned, dicts don't order or unorder the items you put in. It's "magic" as to how it's ordered when you retrieve it. If you want to keep an order -sorted or not- you need to also bind a list or tuple.
This will give you the same dict result with a list that retains order:
greek = ['beta', 'gamma', 'alpha']
d = {}
for x in greek:
d[x[0]] = x
Simply change [] to () if you have no need to change the original list/order.
Don't use a dictionary. Or use the Python 2.7/3.1 OrderedDict type.
There is no order in dictionaries to speak of, there is no original unsorted list.
No, python does not sort dict, it would be too expensive. The order of items() is arbitrary. From python docs:
CPython implementation detail: Keys
and values are listed in an arbitrary
order which is non-random, varies
across Python implementations, and
depends on the dictionary’s history of
insertions and deletions.

Categories