4

Trying to figure out how to sort a list of dictionaries by value, where the value begins with a string in a "custom map" list. So for example, here's the data to sort:

'buckets': [
    {
        'doc_count': 23,
        'key': 'Major League Stuff'
    },
    {
        'doc_count': 23,
        'key': 'Football Stuff'
    },
    {
        'doc_count': 23,
        'key': 'Football Stuff > Footballs'
    },
    {
        'doc_count': 23,
        'key': 'Football Stuff > Footballs > Pro'
    },
    {
        'doc_count': 22,
        'key': 'Football Stuff > Footballs > College'
    },
    {
        'doc_count': 20,
        'key': 'Football Stuff > Football Stuff Collections > Neat Stuff'
    },
    {
        'doc_count': 19,
        'key': 'Football Stuff > Helmets'
    },
    {
        'doc_count': 4,
        'key': 'Jewelry'
    },
    {
        'doc_count': 4,
        'key': 'Jewelry > Rings'
    },
    {
        'doc_count': 2,
        'key': 'All Gifts'
    },
    {
        'doc_count': 2,
        'key': 'Gifts for Her'
    },
    {
        'doc_count': 2,
        'key': 'Gifts for Her > Jewelry'
    },
    {
        'doc_count': 2,
        'key': 'Football Stuff > Footballs > Tykes'
    },
    {
        'doc_count': 1,
        'key': 'Brand new items'
    },
    {
        'doc_count': 1,
        'key': 'Jewelry > Rings and Bands'
    }
    {
        'doc_count': 1,
        'key': 'Football Stuff > Footballs > High School'
    },
    {
        'doc_count': 1,
        'key': 'Football Stuff > Pads'
    }
]

and I want to sort it according to this list:

sort_map = ['Football Stuff',
    'Jewelry',
    'Gifts for Her',
    'Brand new items',
    'Major League Stuff',
    'All Gifts']

I am kind of thinking "startswith" could work, but I am not sure how

buckets = sorted(buckets, key=lambda x: sort_map.index(x['key'].startswith[?]))

Any help appreciated!

Side note - SO is asking me to edit to explain why this post is different than the other "sort dict by value" posts. I did look at as many of those as I could find BEFORE posting this, and there was nothing involving matching parts of strings. So I do believe this is not a duplicate.

tarponjargon
  • 1,002
  • 10
  • 28

2 Answers2

7

I would take advantage of the fact that you can split according to " > " and take the index of the first field

buckets = sorted(buckets, key=lambda x: sort_map.index(x['key'].split(" > ")[0]))

to provide a second alpha criteria, you could return a tuple with the full string as second item so it is sorted alphabetically in case of same index:

buckets = sorted(buckets, key=lambda x: (sort_map.index(x['key'].split(" > ")[0]),x['key']))
Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
0

I think it's better to create a separate function instead of lambda because it makes the code more understandable.

def get_index(x):
    for i, e in enumerate(sort_map):
        if x['key'].startswith(e):
            return i

buckets = sorted(buckets, key=get_index)
Fomalhaut
  • 8,590
  • 8
  • 51
  • 95