1

If I need to sort OrderedDict I used to use such statement that works fine:

from collections import OrderedDict

# defining a dictionary
od = OrderedDict({'a': 5, 'b': 10, 'c': 7})

# ... some changes like adding new keys, removing old keys, etc.

# sorting the dictionary
od_sorted = OrderedDict(sorted(od.items(), key=lambda e: e[1]))

But it has a disadvantage: I create a new OrderedDict instance and list instance (by sorted) that can be expensive regarding memory usage in case if the original dictionary is big. Is there a way to perform sorting inside the original dictionary without creading a new instance or additional objects? I expected to find something like od.sort(key=lambda ...), but found nothing similar:

>>> dir(od)
['__class__', '__contains__', '__delattr__', '__delitem__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'move_to_end', 'pop', 'popitem', 'setdefault', 'update', 'values']

I saw the question How to sort OrderedDict of OrderedDict?, of course. It's said nothing about the efficiency of suggested approaches.

Fomalhaut
  • 8,590
  • 8
  • 51
  • 95
  • 2
    Not efficiently, but there is a `move_to_end` method. `od_keys = (k for k,v in sorted(od.items(), key=lambda e: e[1])); for k in od_keys: od.move_to_end(k)` – Adam Smith Sep 16 '19 at 07:18
  • 1
    My suggestion is to use the `sortedcollections` package -> http://www.grantjenks.com/docs/sortedcollections/. It has the interfaces you expect, the efficiency you'd hope for, and of course has the sorted collections that you want. – alkasm Sep 16 '19 at 07:18
  • @martineau while that appears to be a valid dupe, it's actually _technically_ incorrect and doesn't address the specific need of OP to not duplicate in memory – Adam Smith Sep 16 '19 at 07:20
  • There an old ActiveState `OrderedDict` [recipe](http://code.activestate.com/recipes/576669-ordered-dictionary-for-py27-and-py31/) (by Raymond Hettinger) that internally uses a linked list. You may be able to add a `sort()` method to it that does the re-ordering in-place with very little memory required — performance will depend on the implementation. – martineau Sep 16 '19 at 07:26
  • @AdamSmith: There's nothing technically incorrect about the duplicate I proposed. I also think it very disingenuous of you to edit the OP's question and add something that makes it sound a though they did something you can't be sure is true. – martineau Sep 16 '19 at 07:45
  • @martineau I agree that _would_ be very disingenuous of me. That's why I didn't do that. I haven't edited the question at all, merely answered incorrectly, realized my answer was incorrect, deleted my answer, and noticed you closed with a wrong dupe and reopened. – Adam Smith Sep 16 '19 at 07:56
  • 1
    Note that the original revision of the question included the (still-) bolded statement "Is there a way to perform sorting inside the original dictionary without creading[sic] a new instance." Every answer on your proposed dupe fails this litmus test. – Adam Smith Sep 16 '19 at 07:59
  • 1
    @AdamSmith: I now see that it was in fact the OP, not you, who added the part at the end that begins with "I saw the question" as I originally thought…my apologies. – martineau Sep 17 '19 at 19:18
  • 1
    @martineau no worries :) – Adam Smith Sep 17 '19 at 19:56

1 Answers1

-1

In your case you could still use the ordinary dict instead of OrderedDict because you are not worried about insertion order.

But if you really want to offload the sorting to a thirdparty

You could still use https://github.com/grantjenks/python-sortedcontainers/