0

I am trying to wrap my head around update() and the example I have to go by is

dict = {'Name': 'Zara', 'Age': 7}
dict2 = {'Sex': 'female' }

dict.update(dict2)
print "Value : %s" %  dict

which then outputs

Value : {'Age': 7, 'Name': 'Zara', 'Sex': 'female'}

I understand that you are taking dict and updating it with dict2 but why does the output switch 'Name': 'Zara' with 'Age'? shouldn't %s by the name part? I don't understand that part.

Jaiven
  • 23
  • 1
  • 4
  • 2
    You mean why has the ordering of the output dictionary changed? Because Python dicts are not ordered. This is not something specifically related to the `update` method. – ChidG Apr 13 '17 at 06:12

3 Answers3

1

By design, dictionaries in Python are not ordered. They are optimized to be accessed by key so the insertion order is not important, because the fetching speed is optimized.

There is a separate type called OrderedDict which preserves the order in which the keys are entered.

This "feature" of dictionaries depends on the implementation of Python you are using. In PyPy for example, dictionaries are ordered by default (incidentally, starting from Python 3.6, this same implementation will be part of the "standard" Python (which is implemented in C) as it has other benefits).

You can find our more on the internals by reading the answers to How are Python's Built In Dictionaries Implemented?

Community
  • 1
  • 1
Burhan Khalid
  • 169,990
  • 18
  • 245
  • 284
0

Nothing is being "switched around"; dictionaries are fundamentally unordered.

From the Python Docs on Data Structures (emphasis mine):

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).

This means that the key-value pairs within dicts can be printed out in any order. In this case, they happen to be ordered alphabetically, but this behavior is never guaranteed and cannot be relied upon. The underlying dict has not been "reorganized" in any way by the call to update, it just never had that kind of pair organization.

gyre
  • 16,369
  • 3
  • 37
  • 47
  • Ok, so dict isn't ordered. If this is so I don't understand why every time the results are the exact same. Doesn't that mean it is ordered? So then why did it take dict = {'Name': 'Zara', 'Age': 7} and switch the two but its always the same result if not ordered? Sorry, this has me really hung up for some reason. edit: ok so is it because (A)ge comes before (N)ame, which comes before (S)ex – Jaiven Apr 13 '17 at 06:18
  • They are the same just by random choice - there is a hash that is determined at instantiation, and this is what determines how the dictionary is _printed out_; but at any time this hash may change - which is why the order in which they are printed changes. – Burhan Khalid Apr 13 '17 at 06:20
  • I see your point. The pairs within dictionaries *are* technically stored with some order, but the important part is that that order can change at any time and thus you must never rely upon it. When you created the `dict` literal, you assumed that the order you declared the pairs would match the order they were stored in. – gyre Apr 13 '17 at 06:20
  • When do they change? I just ran the program 30+ times, closed cmd, ran again and it's still always ordered the same way. Do I have to reboot my computer to clear memory or something for there to be no order? I'm getting the same results every time but I'm being told there is no order and it can change. – Jaiven Apr 13 '17 at 06:24
  • And to address your edit, the alphabetical ordering is purely "luck" (based on the hashing implementation), so you can't expect that result (or any other) every time. It probably won't change for you because you are running on a single version of a single implementation of Python (which has a specific hashing algorithm), but if you ran it on a friend's computer or online you might see different results. – gyre Apr 13 '17 at 06:24
  • 1
    Ok, I see it now and I get it. I had to do some runs of the program where I moved stuff around. I added 'Color: 'blue' and it printed the 3 from dict and then the dict2. I then changed the the order of the 3 things in dict and it remained the same when I ran the program again. It seems like you are right and since it has a specific hashing algorithm for my computer. Thanks for the help everyone! – Jaiven Apr 13 '17 at 06:30
-2

According to my understanding, python dictionary does not maintain the insertion order. For example,

In [1]: dict = {'Name': 'Zara', 'Age': 7}

In [2]: dict
Out[2]: {'Age': 7, 'Name': 'Zara'}

In [3]: dict2 = {'Sex': 'female' }

In [4]: dict.update(dict2)

In [5]: print "Value : %s" %  dict
Value : {'Age': 7, 'Name': 'Zara', 'Sex': 'female'}

In [6]: dict.update({'place': 'mangalore'})

In [7]: dict
Out[7]: {'Age': 7, 'Name': 'Zara', 'Sex': 'female', 'place': 'mangalore'}

In [8]: dict.update({'Place': 'mangalore'})

In [9]: dict
Out[9]: 
{'Age': 7,
 'Name': 'Zara',
 'Place': 'mangalore',
 'Sex': 'female',
 'place': 'mangalore'}

In [10]: ord('p')
Out[10]: 112

In [11]: ord('A')
Out[11]: 65

In [12]: dict.update({1: 2})

In [13]: dict
Out[13]: 
{1: 2,
 'Age': 7,
 'Name': 'Zara',
 'Place': 'mangalore',
 'Sex': 'female',
 'place': 'mangalore'}

In [15]: ord('1')
Out[15]: 49

If you see, ord('p') and ord('A'), which is 112 and 65 respectively. That's probably the reason why place came at the bottom and A came before it and '1' came at the top.

A-Z has ascii 65-90 values and a-z has 97-122.

Another Example,

In [16]: d = {'ac':33, 'gw':20, 'ap':102, 'za':321, 'bs':10}

In [17]: d
Out[17]: {'ac': 33, 'ap': 102, 'bs': 10, 'gw': 20, 'za': 321}

If you want to keep track of the insertion order, then you got to use OrderedDict

In [22]: from collections import OrderedDict

In [27]: l = [('ac', 33), ('gw', 20), ('ap', 102), ('za', 321), ('bs', 10)]

In [28]: OrderedDict(l)
Out[28]: OrderedDict([('ac', 33), ('gw', 20), ('ap', 102), ('za', 321), ('bs', 10)])
theBuzzyCoder
  • 2,652
  • 2
  • 31
  • 26
  • 1
    This is not how things work. See http://stackoverflow.com/questions/327311/how-are-pythons-built-in-dictionaries-implemented – Burhan Khalid Apr 13 '17 at 06:34
  • ...and what happens when dictionary keys are not letters but numbers, tuples, or any other type? – Burhan Khalid Apr 13 '17 at 06:35
  • thanks. This post was according to my understanding. – theBuzzyCoder Apr 13 '17 at 06:35
  • ```In [32]: {('ac', 'b'):33, 'gw':20, 'ap':102, 'za':321, 'bs':10, 10002: 3} Out[32]: {10002: 3, 'ap': 102, 'bs': 10, 'gw': 20, 'za': 321, ('ac', 'b'): 33}``` – theBuzzyCoder Apr 13 '17 at 06:37
  • Your understanding is wrong. Please see [this question](http://stackoverflow.com/questions/327311/how-are-pythons-built-in-dictionaries-implemented) for how things actually work. – Burhan Khalid Apr 13 '17 at 06:39