Dictionary sorting

S

Scott Ware

Python newbie here. So, when creating dictionaries, I am noticing that each time I print it out, that its not in the same order as when I typed it in. They seem to be getting sorted somehow. Is there a way to not sort them and leave the order as is?

Thanks!
 
J

John Gordon

In said:
Python newbie here. So, when creating dictionaries, I am noticing that
each time I print it out, that its not in the same order as when I typed
it in. They seem to be getting sorted somehow. Is there a way to not sort
them and leave the order as is?

Dictionaries don't maintain the order of the items.

If you want to keep track of the order in which the items were inserted,
you'll need to do that yourself using a separate mechanism (a list, for
example.)
 
C

Chris Kaynor

Note that there are a number of recipes available for free online, and
if you are using a newer version of Python (2.7 or higher), the
collections module includes an OrderedDict class
(http://docs.python.org/library/collections.html#collections.OrderedDict
- this also include a library for Python 2.4 and higher as well). Note
that there are a lot of different possible behaviors, so any
particular recipe may or may not behave exactly as you desire.

Chris
 
I

insomnia

Moreover, for on-the-fly ordering you can consider to use sorted() on yourdict.keys(), like:

for k in sorted(yourdict.keys()):
print k, yourdict[k]

I think it has no side effects, except that the orderering can be slow on huge data sets, and that you need to call it every time after updating the dict keys.

Regards,
insomniac
 
T

Terry Reedy

Python newbie here. So, when creating dictionaries, I am noticing
that each time I print it out, that its not in the same order as when
I typed it in. They seem to be getting sorted somehow.

No, the entries are not being sorted at all.
Is there a way to not sort them and leave the order as is?

CPython iterates (and prints) dict items in their arbitrary internal
hash table order, which depends on the number and entry order of the
items. It is a bug to depend on that arbitrary order in any way.

If you want to keep the dict sorted by entry order (as far as the user
view goes), use collections.OrderedDict.
 
T

Tim Chase

CPython iterates (and prints) dict items in their arbitrary internal
hash table order, which depends on the number and entry order of the
items. It is a bug to depend on that arbitrary order in any way.

Does this "never trust it" hold even for two consecutive
iterations over an unchanged dict? I didn't see anything in the
docs[1] to make such a claim, but at least from my experience,
one can reliably assert

d = {}
randomly_populate(d)
list1 = list(d.iterkeys())
list2 = list(d.iterkeys())
assert list1 == list2

I understand all bets are off if one adds/removes (or maybe
changes the values) of the dict between iterations, but I didn't
know if what I saw was merely an implementation detail that
shouldn't be counted on.

-tkc

[1]
http://docs.python.org/library/stdtypes.html#mapping-types-dict
 
C

Chris Angelico

list1 = list(d.iterkeys())
 list2 = list(d.iterkeys())
 assert list1 == list2

There is such a guarantee in Python 2. From
http://docs.python.org/library/stdtypes.html:
"If items(), keys(), values(), iteritems(), iterkeys(), and
itervalues() are called with no intervening modifications to the
dictionary, the lists will directly correspond. This allows the
creation of (value, key) pairs using zip(): pairs = zip(d.values(),
d.keys()). The same relationship holds for the iterkeys() and
itervalues() methods: pairs = zip(d.itervalues(), d.iterkeys())
provides the same value for pairs. Another way to create the same list
is pairs = [(v, k) for (k, v) in d.iteritems()]."

Python 3 does things quite differently (with views), and I can't find
a corresponding promise, but I expect that this would still be the
case.

ChrisA
 
H

Hrvoje Niksic

Ben Finney said:
Tim Chase said:
CPython iterates (and prints) dict items in their arbitrary internal
hash table order, which depends on the number and entry order of the
items. It is a bug to depend on that arbitrary order in any way.

Does this "never trust it" hold even for two consecutive iterations
over an unchanged dict? I didn't see anything in the docs[1] to make
such a claim,

Exactly.

This is false. The docs say:

If items(), keys(), values(), iteritems(), iterkeys(), and
itervalues() are called with no intervening modifications to the
dictionary, the lists will directly correspond. This allows the
creation of (value, key) pairs using zip(): pairs = zip(d.values(),
d.keys()).

(http://docs.python.org/library/stdtypes.html#mapping-types-dict)
The order of retrieval is entirely up to the implementation.

This part is still true, but the order won't change behind your back if
you're not touching the dict.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,772
Messages
2,569,593
Members
45,111
Latest member
VetaMcRae
Top