Sherlock
Sherlock

Reputation: 73

Need help in extracting value counts from a list of dictionaries using python

I am looking to calculate the % of values against keys from a List of dictionaries and their corresponding counts along with values and their corresponding count using Python.

Used below code to extract keys and their count. Need help in expanding it to extract values and their corresponding count.

The Data looks like this:

people = [
    {"name": "Tom", "age": 10, "city": "NewYork"},
    {"name": "Mark", "age": 5, "country": "Japan"},
    {"name": "Pam", "age": 7, "city": "London"},
    {"name": "Tom", "hight": 163, "city": "California"},
    {"name": "Lena", "weight": 45, "country": "Italy"},
    {"name": "Ben", "age": 17, "city": "Colombo"},
    {"name": "Lena", "gender": "Female", "country": "Italy"},
    {"name": "Ben", "gender": "Male", "city": "Colombo"},
]


def getKeyCount(lst):
    out = {}
    for d in lst:
        for k in d.keys():
            out[k] = out.get(k, 0) + 1
    return out


def getValCount(lst):
    out = {}
    for d in lst:
        for v in d.values():
            out[v] = out.get(v, 0) + 1
    return out


getKeyCount(people)
# {'name': 8, 'age': 4, 'city': 5, 'country': 3,
# 'hight': 1, 'weight': 1, 'gender': 2}

getValCount(people)
# {'Tom': 2, 'NewYork': 1, 'Mark': 1, 'Japan': 1, 'Pam': 1,
# 'London': 1, 'California': 1, etc.}

I want output like this:

Name: 10
'Tom': 2, 'Mark': 3, 'Pam': 1,'Lena': 3, 'Ben': 2
City:4
'London': 1, 'California': 1, 'NewYork': 2

I am new to this, can someone help me?

Upvotes: 1

Views: 236

Answers (2)

Andrej Kesely
Andrej Kesely

Reputation: 195448

Try:

from collections import Counter, defaultdict

people = [
    {"name": "Tom", "age": 10, "city": "NewYork"},
    {"name": "Mark", "age": 5, "country": "Japan"},
    {"name": "Pam", "age": 7, "city": "London"},
    {"name": "Tom", "hight": 163, "city": "California"},
    {"name": "Lena", "weight": 45, "country": "Italy"},
    {"name": "Ben", "age": 17, "city": "Colombo"},
    {"name": "Lena", "gender": "Female", "country": "Italy"},
    {"name": "Ben", "gender": "Male", "city": "Colombo"},
]

cnt = defaultdict(Counter)
for p in people:
    if not isinstance(p, dict):  # <-- make sure the items are dicts
        continue

    for k, v in p.items():
        cnt[k].update([v])

for k, v in cnt.items():
    print(k, sum(cnt[k].values()))
    for kk, vv in v.items():
        print("{}: {}".format(kk, vv), end=" ")
    print("\n")

Prints:

name 8
Tom: 2 Mark: 1 Pam: 1 Lena: 2 Ben: 2 

age 4
10: 1 5: 1 7: 1 17: 1 

city 5
NewYork: 1 London: 1 California: 1 Colombo: 2 

country 3
Japan: 1 Italy: 2 

hight 1
163: 1 

weight 1
45: 1 

gender 2
Female: 1 Male: 1 


UPDATE: Added check that values are of type dict

Upvotes: 1

Red
Red

Reputation: 27567

You can try the list.count method on every value to get the count of each value:

people = [{'name': "Tom", 'age': 10, "city" : "NewYork"},
          {'name': "Mark", 'age': 5, "country" : "Japan"},
          {'name': "Pam", 'age': 7, "city" : "London"},
          {'name': "Tom", 'hight': 163, "city" : "California"},
          {'name': "Lena", 'weight': 45, "country" : "Italy"},
          {'name': "Ben", 'age': 17, "city" : "Colombo"},
          {'name': "Lena", 'gender': "Female", "country" : "Italy"},
          {'name': "Ben", 'gender': "Male", "city" : "Colombo"}]

def getKeyCount(lst):
    out = {}
    for d in lst:
        for k in d:
            out[k] = out.get(k, []) + [d[k]]
    return out

d = getKeyCount(people)

def display(d, key):
    vals = d[key]
    print("Name:", len(vals))
    print(', '.join(f"{val}: {vals.count(val)}" for val in set(vals)))

display(d, 'name')
display(d, 'city')

Output:

Name: 8
Mark: 1, Ben: 2, Tom: 2, Pam: 1, Lena: 2
City: 5
London: 1, NewYork: 1, Colombo: 2, California: 1

Upvotes: 0

Related Questions