0

When sorting on a list of dictionaries, it is possible to ensure consistency and the desired sort-order by specifying one or more keys.

For example, given a list L:

L = [{'a':1, 'b':2}, {'b':1, 'a':2}]
sorted(L, key=lambda dic:dic['a'])

returns

[ {'a': 1, 'b': 2} , {'a': 2, 'b': 1} ]

Similarly,

sorted(L, key=lambda dic:dic['b'])

returns

[ {'a': 2, 'b': 1} , {'a': 1, 'b': 2} ]

When not providing a key, i.e. just using sorted(L) I am observing a sort order identical to the first sort expression. How exactly is a key chosen when not provided?

Background: My final goal is to write a generic comparator (self.__eq__) for a custom class, the basis of equality for which will be a number of properties one or more of which may be list of dictionaries. Since it is difficult to provide a sort key as fields within the dictionary that forms the list may not be known beforehand I was considering skipping the use of a key altogether to force the default. My gut feeling is that sorted will yield the same result for a compound type regardless of original order in the absence of a key, but I haven't found any documentation to support this. Can someone explain?

Edit: I cannot understand why this was marked as a duplicate of the solution to explanation for dict.__cmp__ ? I am trying to sort a list, not a dictionary. I do not care how the constituent dictionaries are ordered but what matters is the place of any dictionary in the list for list vs list comparison. With a normal list once could do set(L1)==set(L2) to compare contents, however, my goal is try and compare two lists when the contents are dictionaries and this is why I need to sort them.

Community
  • 1
  • 1
Spade
  • 2,220
  • 1
  • 19
  • 29
  • 2
    When calling `sorted(L)`, the order in which the elements of `L` are arranged depends on how `__cmp__` is implemented on them. In your case, the elements are dicts, hence the order depends on the behaviour of `dict.__cmp__`. Hence, the question was closed as a duplicated. – Frerich Raabe Jun 10 '15 at 06:11
  • Okay, thanks for adding this. I think this would have better a better answer than the question being marked duplicate. – Spade Jun 10 '15 at 06:22

1 Answers1

0

use def __cmp__(self,other) for a comparator.

dictionaries by definition have no order.... therefor there sort behavior is undefined without further specification, you cannot rely on anything ...(actually I sort of retract this given the potential dupe target in the comments of OP ... I still say you should not sort dictionaries without explicitly telling it how you want it sorted)

sorted([(1,2,3),(4,5,6),(7,8)])

will sort on the first item in the list ... in the event of a tie it will sort on the second item in the list and so on

Joran Beasley
  • 110,522
  • 12
  • 160
  • 179
  • Thanks for trying to answer. Please note that I am not trying to sort a dictionary but a list here. I can't see why this is a duplicate as you marked – Spade Jun 10 '15 at 06:01
  • that dupe explains how a dictionary is compared to another dictionary ... this answer is one of many that explains how lists are sorted .... I also recommend using `def __cmp__` to implement your comparator on a custom class(as opposed to `self.__eq__`) ... if neither answers your question perhaps you could try rephasing the question somehow... – Joran Beasley Jun 10 '15 at 06:07
  • I think the first comment, added later on the question explained how a default key is chosen : I guess by going down the compound data type depth wise, so `__cmp__` is attempted on dict which is undefined. However, I was inclined to implement rich comparison `__eq__` as I only see the application for `==` not `>=` or `<=`. The class is a genome. I kind of agree with the philosophy in http://gerg.ca/blog/post/2012/python-comparison/ – Spade Jun 10 '15 at 06:35