简体   繁体   中英

Complex sort dictionary into sorted list

I have the following class:

class SalesRecord:
    name = ''
    dollarsSpent = 0
    itemsPurchased = 0
    itemsSold = 0
    position = 0

I also have a dictionary that is structured with a bunch of these SalesRecords with the SalesRecord.name as the key. How can I sort the values into a sorted list with the following criteria (Assume everything is an integer):

  1. Sort by dollarsSpent desc
  2. Then by itemsPurchased - itemsSold desc
  3. Then by itemsPurchased desc
  4. Then by position asc

Also, just curious, but what would the overall run-time of such a sort be? Does it need to iterate 4 times in the worst case?

Use a compound key.

sorted((k, v) for (k, v) in somedict, key=lambda (k, v):
  (-v.dollarsSpent, -(v.itemsPurchased - v.itemsSold),
  -v.itemsPurchased, v.position))

You have two options. Both options run in linearithmic time, O(nlog(n)) , but you may consider one more readable. You can use a compound sort key:

def sortkey(salesrecord):
    r = salesrecord
    return (
        -r.dollarsSpent,
        -r.itemsPurchased + r.itemsSold,
        -r.itemsPurchased,
        r.position
    )
sorted(salesdict.values(), key=sortkey)

or sort multiple times, relying on the stability of the sort algorithm:

l = salesdict.values()
l.sort(key=lambda r: r.position)
l.sort(key=lambda r: r.itemsPurchased, reverse=True)
l.sort(key=lambda r: r.itemsPurchased - r.itemsSold, reverse=True)
l.sort(key=lambda r: r.dollarsSpent, reverse=True)

With a stable sort , you can sort by a number of keys with different priorities by sorting by each key from lowest priority to highest. After sorting by a higher-priority key, items that compare equal by that key are guaranteed to remain in the order they had after the lower-priority key sorts.

The easiest approach is to take advantage of sort stability to sort in multiple stages (first by position, then by items purchased descending, etc).

This is less expensive than it seems because the TimSort algorithm takes advantage the elements that are already partially ordered.

This approach is also easier to get right than trying to build an overly complex key-function .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM