3

I want to retrieve only the fourth item in the dictionary "e" (below).

I tried using the OrderedDict() method, but it didn't work. Here are my results:

from collections import OrderedDict

e = OrderedDict()
e = {'a': 'A',
     'b': 'B',
     'c': 'C',
     'd': 'D',
     'e': 'E'
    }

for k, v in e.items():
    print k, v

print e.items()[3]

The last line returns: ('e', 'E')

So I turned the keys and values into lists, but here's how the lists appeared when I printed them:

['a', 'c', 'b', 'e', 'd']


['A', 'C', 'B', 'E', 'D']

For me, this explained why it happened, but not how it happened.

So, next I sorted them. That gave me the results I was looking for -- but it seemed unnecessarily complicated:

e = {'a': 'A',
     'b': 'B',
     'c': 'C',
     'd': 'D',
     'e': 'E'
}
k, v = sorted(e.keys()), sorted(e.values())
print "{}: {}".format(k[3], v[3])

Result: d: D

OrderedDict() wasn't necessary.

Is there an easier way to do this? And can someone explain why the elements in the dictionary are ordered like this:

keys: 'a', 'c', 'b', 'e', 'd'


values: 'A', 'C', 'B', 'E', 'D'

... which defies the structure of my original dictionary?

fra
  • 205
  • 1
  • 3
  • 7
  • 1
    When you do this: `e = {'a': 'A'...` you overwrite the `OrderedDict` with an ordinary dictionary. Try `e.update({'a', 'A'...})` instead. Edit: Actually, don't try that, it doesn't work either! It just iterates over the dictionary in the default order, which isn't what you want. OK, do _this_: `e = OrderedDict((('a', 'A'), ('b', 'B')...`. – senderle Jan 08 '15 at 01:46
  • 2
    @senderle: as soon as the ordinary dictionary is made the ordering the OP expects is lost; updating from a dict literal isn't going to help. (Of course I know you know this..) – DSM Jan 08 '15 at 01:48
  • 1
    "OrderedDict() wasn't necessary." is only true because you have monotonically increasing keys and values; that is a rare occurrence in real code. Given `{1: 2, 2: 1}` your sorted keys and sorted value method fails. Use an OrderedDict after reading about how standard `dict`s are ordered. – msw Jan 08 '15 at 02:02
  • @msw: it seems that it does that the keys() values() method does still work -- even given the `{1:2, 2:1}` dictionary. But my "solution" still doesn't give me dictionary element, per se; it's still the result of two lists converted from the keys and values of the original dictionary. edit: No, it doesn't work. I see that now. – fra Jan 08 '15 at 04:47

1 Answers1

5

You're not using an ordered dict.

e = OrderedDict()
e = {'a': 'A',
     'b': 'B',
     'c': 'C',
     'd': 'D',
     'e': 'E'
    }

The first line creates an OrderedDict. The second line throws it away and replaces it with a regular dict, which is unordered. (Python variables don't have types.)

But you can't just do this:

e = OrderedDict({'a': 'A', ...})

...because that's still a regular dict, which is still unordered, and OrderedDict can't magically recreate your original source ordering.

Try this:

e = OrderedDict([('a', 'A'), ('b', 'B'), ...])

Now you should have a dict-like object with the ordering you want.

And can someone explain why the elements in the dictionary are ordered like this ... which defies the structure of my original dictionary?

Because dictionaries are unordered. They're just hash maps, and hash maps have no inherent ordering.


Note that you could also do this, which will preserve the pairing of keys and values (whereas your separate sortings will not):

print sorted(e.items())[3]
Eevee
  • 47,412
  • 11
  • 95
  • 127
  • Thank you for that explanation. But how then IS the dictionary ordered? It has to follow some paradigm, or it would be different every time. – fra Jan 08 '15 at 01:51
  • 2
    @user1303778: that's a long story -- see [here](http://stackoverflow.com/questions/15479928/why-is-the-order-in-python-dictionaries-and-sets-arbitrary) and [here](http://stackoverflow.com/questions/327311/how-are-pythons-built-in-dictionaries-implemented), among others, for summaries. – DSM Jan 08 '15 at 01:56