AlexW
AlexW

Reputation: 2587

ordering a dictionary by count of items across a number of key value lists

hopefully he the title is not too confusing, I have a dictionary (sample below) whereby im trying to sort the dictionary by the number of list (dictionary items) across a number of key values beneath a parent. Hopefully the example makes more sense then my description?

{
    "data": {
        "London": {
            "SHOP 1": [
                {
                    "kittens": 10,
                    "type": "fluffy"
                },
                {
                    "puppies": 11,
                    "type": "squidgy"
                }
            ],
            "SHOP 2": [
                {
                    "kittens": 15,
                    "type": "fluffy"
                },
                {
                    "puppies": 3,
                    "type": "squidgy"
                },
                {
                    "fishes": 132,
                    "type": "floaty"
                }
            ]
        },
        "Manchester": {
            "SHOP 1": [
                {
                    "kittens": 10,
                    "type": "fluffy"
                },
                {
                    "puppies": 11,
                    "type": "squidgy"
                }
            ],
            "SHOP 2": [
                {
                    "kittens": 15,
                    "type": "fluffy"
                },
                {
                    "puppies": 3,
                    "type": "squidgy"
                },
                {
                    "fishes": 132,
                    "type": "floaty"
                }
            ],
            "SHOP 3": [
                {
                    "kittens": 15,
                    "type": "fluffy"
                },
                {
                    "puppies": 3,
                    "type": "squidgy"
                },
            ]
        },
        "Edinburgh": {
            "SHOP 1": [
                {
                    "kittens": 10,
                    "type": "fluffy"
                },
                {
                    "puppies": 11,
                    "type": "squidgy"
                }
            ],
            "SHOP 2": [
                {
                    "kittens": 15,
                    "type": "fluffy"
                },
            ],
            "SHOP 3": [
                {
                    "puppies": 3,
                    "type": "squidgy"
                },
            ]
        }
    }
}

Summary

# London 2 shops, 5 item dictionaries total
# Machester 3 shops, 7 item dictionaries total
# Edinburgh 3 shops, 4 item dictionaries total

Desired sorting would be by total items across the shops, so ordered Manchester, London, Edinburgh

id usually use somethign like the below to sort, but im not sure how to do this oen with it being counting the number of items across a number of keys?

{k: v for k, v in sorted(x.items(), key=lambda item: item[1])}

Upvotes: 0

Views: 45

Answers (2)

funnydman
funnydman

Reputation: 11346

No need to make things complex:

adict = adict['data']
result = []
for capital, value in adict.items():
    shop_count = len(value)
    items = sum([len(obj) for obj in value.values()])
    result.append((capital, shop_count, items))


for capital, shop_count, items in sorted(result, key=lambda x: x[2], reverse=True):
    print(f'{capital} {shop_count} shops, {items} item dictionaries total')

Output:

Manchester 3 shops, 7 item dictionaries total
London 2 shops, 5 item dictionaries total
Edinburgh 3 shops, 4 item dictionaries total

Upvotes: 0

Nick
Nick

Reputation: 147196

You need to reverse sort based on the total number of items for each location, which you can generate as:

sum(len(i) for i in s.values())

where s is the shop dictionary for each location.

Putting this into a sorted expression:

dict(sorted(d['data'].items(), key=lambda t:sum(len(i) for i in t[1].values()), reverse=True))

gives:

{
  'Manchester': {
    'SHOP 1': [{'kittens': 10, 'type': 'fluffy'}, {'puppies': 11, 'type': 'squidgy'}], 
    'SHOP 2': [{'kittens': 15, 'type': 'fluffy'}, {'puppies': 3, 'type': 'squidgy'}, {'fishes': 132, 'type': 'floaty'}],
    'SHOP 3': [{'kittens': 15, 'type': 'fluffy'}, {'puppies': 3, 'type': 'squidgy'}]
  },
  'London': {
    'SHOP 1': [{'kittens': 10, 'type': 'fluffy'}, {'puppies': 11, 'type': 'squidgy'}], 
    'SHOP 2': [{'kittens': 15, 'type': 'fluffy'}, {'puppies': 3, 'type': 'squidgy'}, {'fishes': 132, 'type': 'floaty'}]
  },
  'Edinburgh': {
    'SHOP 1': [{'kittens': 10, 'type': 'fluffy'}, {'puppies': 11, 'type': 'squidgy'}],
    'SHOP 2': [{'kittens': 15, 'type': 'fluffy'}], 'SHOP 3': [{'puppies': 3, 'type': 'squidgy'}]
  }
}

Upvotes: 1

Related Questions