7

I am trying to learn Python from some tutorial. Here is a simple example I encountered that puzzles me.

>>> d={"server":"mpilgrim", "database":"master", "uid":"sa", "pwd":"secret"}

>>> d
{'pwd': 'secret', 'database': 'master', 'uid': 'sa', 'server': 'mpilgrim'}

>>> d.keys()
['pwd', 'database', 'uid', 'server']

>>> d.values()
['secret', 'master', 'sa', 'mpilgrim']

As you can see in the first line where I define the dictionary, the item "pwd":"secret" is the last element in the dictionary. However, when I output the dictionary, it became the first element. And the rest part of the dictionary has been reordered.

May I know why this is happening?

If I use dict.keys() to extract the keys from a dictionary and iterate it in an order that I suppose it to be, will that cause mismatch problem?

Amit G
  • 186
  • 1
  • 11
ChangeMyName
  • 7,018
  • 14
  • 56
  • 93

7 Answers7

12

May I know why this is happening?

It is because of the way dicts are organized internally.

In short, this works via a hash-table which puts the keys into buckets according to their hash() value.

If I use dict.keys() to extract the keys from a dictionary and iterate it in an order that I suppose it to be, will that cause dismatch problem?

Depending on how you do it.

k = list(d.keys())
k.sort()
for i in k: print i, d[i]

should exactly work how you want it to work.

glglgl
  • 89,107
  • 13
  • 149
  • 217
5

If you want to maintain the insertion order, you can use OrderedDict. But regular dict objects store the values by hashing the key and using that for lookups, which doesn't keep the order, but makes lookup faster.

Brett Stottlemyer
  • 2,734
  • 4
  • 26
  • 38
4

All you have to worry about is, you are getting value corresponding to the key or not and that is guaranteed by dict.

d={"server":"mpilgrim", "database":"master", "uid":"sa", "pwd":"secret"}
for k, v in d.items():
    print k, v

Output

pwd secret
database master
uid sa
server mpilgrim

Note: If you really want the order of the keys to be predictable, set PYTHONHASHSEED environmental variable an integer value in the range [0,4294967295]. Quoting from python --help

PYTHONHASHSEED: if this variable is set to 'random', the effect is the same as specifying the -R option: a random value is used to seed the hashes of str, bytes and datetime objects. It can also be set to an integer in the range [0,4294967295] to get hash values with a predictable seed.

thefourtheye
  • 233,700
  • 52
  • 457
  • 497
2

It is because dictionaries are not sorted.You cannot influence the key order in any way. There is Collections.OrderedDict to maintain the insertion order.

Prashant Gaur
  • 9,540
  • 10
  • 49
  • 71
1

Dictionaries are not sorted! Use the Key Value to get the item you want.

Mailerdaimon
  • 6,003
  • 3
  • 35
  • 46
0

May I know why this is happening?

This is because Python's dictionary does not have a predefined order. Think of it as a key-value store. And do not expect an exact ordering of keys and values.

What you can perhaps do, if you need an ordering in a dictionary is to use an OrderedDict.

UltraInstinct
  • 43,308
  • 12
  • 81
  • 104
0

In general dictionaries are not sorted. They are grouped by key/value pairs. They are generally fast as they are hash mapped. If you know the key you can quickly get its value.

for example if you wanted to get the value of server one would do this

d['server'] and you would have your answer...

Div
  • 130
  • 1
  • 14