Reputation: 11
For ex:
people_list = [{"name":"joe", "age":20}, {"name":"tom", "age":35}, {"name":"joe", "age":46}]
How do I check if any key-value pair appears more than once in this list of dictionaries?
I am aware of the counter function.
from collections import Counter
for i in range(len(people_list):
Counter(people_list[i]["name"])
for key,value in Counter:
if Counter(key:value) > 1:
...
Just not sure how to make it look and count for a specific key value pair in this list of dictionaries and check if it appears more than once.
Upvotes: 1
Views: 799
Reputation: 28
I would convert each pair into a string representation and then put it on a list. After that you can use the Counter
logic that is already present in this question. Granted that this is not the most effective way to treat the data, but it is still a simple solution.
from functools import reduce
from collections import Counter
people_list = [{"name":"joe", "age":20}, {"name":"tom", "age":35}, {"name":"joe", "age":46}]
str_lists = [[f'{k}_{v}' for k,v in value.items()] for value in people_list]
# [['name_joe', 'age_20'], ['name_tom', 'age_35'], ['name_joe', 'age_46']]
normalized_list = list(reduce(lambda a,b: a+b,str_lists))
# ['name_joe', 'age_20', 'name_tom', 'age_35', 'name_joe', 'age_46']
dict_ = dict(Counter(normalized_list))
# {'name_joe': 2, 'age_20': 1, 'name_tom': 1, 'age_35': 1, 'age_46': 1}
print([k for k,v in dict_.items() if v>1])
# ['name_joe']
Upvotes: 0
Reputation: 44148
You want to take all the key/value pairs in each dictionary and add them to a Counter
instance whose key is (key, value) and whose value will end up being the number of times this pair exists:
from itertools import chain
from collections import Counter
l = [
{"name":"joe", "age":20},
{"name":"tom", "age":35},
{"name":"joe", "age":46}
]
c = Counter(chain.from_iterable(d.items() for d in l))
# Now build the new list of tuples (key-name, key-value, count-of-occurrences)
# but include only those key/value pairs that occur more than once:
l = [(k[0], k[1], v) for k, v in c.items() if v > 1]
print(l)
Prints:
[('name', 'joe', 2)]
If you want to create a new list of dictionaries where the 'name' key values are all the distinct name values in the original list of dictionaries and whose value for the 'age' key is the sum of the ages for that name, then:
from collections import defaultdict
l = [
{"name":"joe", "age":20},
{"name":"tom", "age":35},
{"name":"joe", "age":46}
]
d = defaultdict(int)
for the_dict in l:
d[the_dict["name"]] += the_dict["age"]
new_l = [{"name": k, "age": v} for k, v in d.items()]
print(new_l)
Prints:
[{'name': 'joe', 'age': 66}, {'name': 'tom', 'age': 35}]
Upvotes: 2
Reputation: 5559
You can use a Counter
to count the number of occurrences of each value and check if any key-value pair appears more than once.
from collections import Counter
people_list = [{"name":"joe", "age":20}, {"name":"tom", "age":35}, {"name":"joe", "age":46}]
# Count the number of occurrences of each value
counts = Counter(d["name"] for d in people_list)
# Check if any key-value pair appears more than once
for key, value in counts.items():
if value > 1:
print(f"{key} appears more than once")
Gives:
joe appears more than once
Upvotes: 0
Reputation: 350310
If you want to get as output "joe", because it appears more than once for the key "name", then:
from collections import Counter
people_list = [{"name":"joe", "age":20}, {"name":"tom", "age":35}, {"name":"joe", "age":46}]
counter = Counter([person["name"] for person in people_list])
print([name for name, count in counter.items() if count > 1]) # ['joe']
Upvotes: 1
Reputation: 24049
You can use collections.Counter
and update
like the below:
from collections import Counter
people_list = [{"name":"joe", "age":20}, {"name":"tom", "age":35}, {"name":"joe", "age":46}]
cnt = Counter()
for dct in people_list:
cnt.update(dct.items())
print(cnt)
# Get the items > 1
for k,v in cnt.items():
if v>1:
print(k)
Output:
Counter({('name', 'joe'): 2, ('age', 20): 1, ('name', 'tom'): 1, ('age', 35): 1, ('age', 46): 1})
('name', 'joe')
Upvotes: 1