Reputation: 79
I have an array of dicts. This works
tickets.sort(key=itemgetter('start'))
, however if the starts equal each other, I need a second criteria to sort by (If there's an easy way to do this, that would solve everything), so I'd like to write my own sort. I've done it before, in the form
tickets.sort(sort_function)
but it doesn't work with this, I get
unhashable type: 'dict' error.
Is there a way to do this?
EDIT
I forgot something important. For the second criteria, it's not a simple greater/less than case. It's along the lines of if start == "specific", return -1
Upvotes: 0
Views: 187
Reputation: 2196
…however if the starts equal each other, I need a second criteria to sort by (If there's an easy way to do this, that would solve everything)
There is an easy way to do this: use a tuple for each item's key. Because tuple comparison treats earlier items as more significant, later items are only considered when earlier ones match.
For example, given a list of items with two numbers, where sorting should be ascending on the first (more significant) number and descending on the second:
>>> data = [
... (1, 0),
... (1, 1),
... (1, 2),
... (0, 0),
... (2, 0),
... ]
>>> data.sort(key=lambda (a, b): (a, -b))
>>> data
[(0, 0), (1, 2), (1, 1), (1, 0), (2, 0)]
I forgot something important. For the second criteria, it's not a simple greater/less than case. It's along the lines of if start == "specific", return -1
Use your special values in later items of the tuple in a way that turns them into a simple <, ==, or > comparison:
def ticket_key(ticket):
start = ticket["start"]
if start == "specific":
second = -1
else:
second = ticket["blah"]
return (start, second)
tickets.sort(key=ticket_key)
Now for items where ticket["start"] is "specific", -1 is used instead of ticket["blah"]:
>>> data = [
... {"start": "specific"}, # "blah" doesn't even exist here
... {"start": "specific", "blah": 2},
... {"start": "42", "blah": 1},
... {"start": "42", "blah": 0},
... ]
>>> data.sort(key=ticket_key)
>>> data
[{'start': '42', 'blah': 0},
{'start': '42', 'blah': 1},
{'start': 'specific'},
{'start': 'specific', 'blah': 2}]
Upvotes: 1
Reputation: 2028
I think your problem is that the function you wrote somehow tries to use a dictionary as a key for another dictionary. Since dictionaries are unhashable, you get that error.
Upvotes: 0
Reputation: 47988
You can simply pass a second parameter to itemgetter and it will create the necessary function for you:
tickets.sort(key = itemgetter('start', 'end'))
Upvotes: 5