how to count duplicate of dictionarys inside the list? - python

Was wondering if anyone could help me with counting duplicate dictionarys. I have this list:
a = [{'key1':1, 'key2':2, 'key3':3, 'count': 0},
{'key1':1, 'key2':2, 'key3':4, 'count': 0},
{'key1':3, 'key2':2, 'key3':4, 'count': 0},
{'key1':1, 'key2':2, 'key3':3, 'count': 0}]
i`m lookig to count all duplicates and once it is match remove copy and append to that dictionry ['count'] += 1. so final result might look like
a = [{'key1':1, 'key2':2, 'key3':3, 'count': 2},
{'key1':1, 'key2':2, 'key3':4, 'count': 0},
{'key1':3, 'key2':2, 'key3':4, 'count': 0}]
i did tryed simple aprouch such as which didnt worked:
a = [{'key1':1, 'key2':2, 'key3':3, 'count': 0},
{'key1':1, 'key2':2, 'key3':4, 'count': 0},
{'key1':3, 'key2':2, 'key3':4, 'count': 0},
{'key1':1, 'key2':2, 'key3':3, 'count': 0}]
for i in range(len(a)):
for n in range(len(a)):
if a[i]['key1'] == a[n]['key1'] and a[i]['key2'] == a[n]['key2'] and a[i]['key3'] == a[n]['key3']:
a[i]['count'] += 1
del a[n]
was thinking aswell there should be some simpler aprouch. thanks

You can leverage Counter method in the collections module.
import collections
count = collections.Counter([tuple(d.items()) for d in a])
[dict(k) | {c:v} for (*k, (c,_)), v in count.items()]
this looks like:
[{'key1': 1, 'key2': 2, 'key3': 3, 'count': 2},
{'key1': 1, 'key2': 2, 'key3': 4, 'count': 1},
{'key1': 3, 'key2': 2, 'key3': 4, 'count': 1}]

Related

Summation on an element inside nested dicts in a list

I have a list of nested dictionaries
timedata = [
{'time': 1, 'distance': {'a': 300, 'b': 3}},
{'time': 2, 'distance': {'a': 600, 'b': 1}},
{'time': 3, 'distance': {'a': 600, 'b': 4}},
{'time': 4, 'distance': {'a': 300, 'b': 3}},
]
Any ideas how to calculate the summation of 'a' from all dicts inside the list?
To go inside timedata, use [], similarly for nestings inside it. To sum conttents, use sum():
print(sum([di['distance']['a'] for di in timedata]))
try this;
sum = 0
for i in timedata:
sum += i['distance']['a']
print(sum)

Identifying specific string and place it in the same index

Related to my previous post, would it be possible to separate the list of weirdly combined animals and their attribute (denoted in #)?
Dataset:
the_list = pd.Series([["dog", "cat", "#paws"],["gorilla"],["goat", "#beard","#hoofs"],["goldfish", "#fins", "#bigeyes", "#scales"]])
My Code:
category1 = []
category2 = []
for word_list in the_list:
category1.append([{v : 1} for v in word_list if not "#" in v])
category2.append([{v : 1} for v in word_list if "#" in v])
Here's the result:
Category 1:
[{'dog': 1}, {'cat': 1}, {'gorilla': 1}, {'goat': 1}, {'goldfish': 1}]
Category 2:
[[{'#paws': 1}],
[],
[{'#beard': 1}, {'#hoofs': 1}],
[{'#fins': 1}, {'#bigeyes': 1}, {'#scales': 1}]]
But what I need is to join all the elements of the same index instead of creating a separate dictionary for them
Category1:
[{'dog': 1, 'cat': 1},
{'gorilla': 1},
{'goat': 1},
{'goldfish': 1}]
Category2:
[{'#paws': 1}, # from dog, cat
{'No Category 2': 1}, #from gorilla
{"#beard" : 1,"#hoofs" : 1}, #from goat
{'#fins': 1, '#bigeyes': 1, '#scales': 1}] #from goldfish
Use dict.fromkeys:
category1 = []
category2 = []
for word_list in the_list:
category1.append(dict.fromkeys([v for v in word_list if not '#' in v] or ['No Category 1'], 1))
category2.append(dict.fromkeys([v for v in word_list if '#' in v] or ['No Category 2'], 1))
Output:
#category1
[{'cat': 1, 'dog': 1}, {'gorilla': 1}, {'goat': 1}, {'goldfish': 1}]
#category2
[{'#paws': 1},
{'No Category 2': 1},
{'#beard': 1, '#hoofs': 1},
{'#bigeyes': 1, '#fins': 1, '#scales': 1}]
Use dict
Ex:
category1 = []
category2 = []
the_list = pd.Series([["dog", "cat", "#paws"],["gorilla"],["goat", "#beard","#hoofs"],["goldfish", "#fins", "#bigeyes", "#scales"]])
for word_list in the_list:
category1.append(dict((v , 1) for v in word_list if not "#" in v))
category2.append(dict((v , 1) for v in word_list if "#" in v) or {'No Category 2': 1})
Output:
[{'cat': 1, 'dog': 1}, {'gorilla': 1}, {'goat': 1}, {'goldfish': 1}]
[{'#paws': 1},
{'No Category 2': 1},
{'#beard': 1, '#hoofs': 1},
{'#bigeyes': 1, '#fins': 1, '#scales': 1}]

Sort a list of one value dictionaries

I have data:
{'foo': [{1: 55}, {'c': 43}], 'bar': [{1: 43}, {'c': 40}]}
I wanna sort the dictionaries inside the foo and bar by its values:
{'foo': [{'c': 43}, {1: 55}], ...}
I dont wanna sort the 'foo' and 'bar'.
Is there an easy way yo do this? Sorry if I make mistake in writing the dicts/lists. Thanks
Here is one way. sorted accepts a key argument which accepts an anonymous lambda function. Since each dictionary only has one key/value, you can list your values and select the first.
d = {'foo': [{1: 55}, {'c': 43}], 'bar': [{1: 43}, {'c': 40}]}
res = {k: sorted(v, key=lambda x: list(x.values())[0]) for k, v in d.items()}
# {'bar': [{'c': 40}, {1: 43}], 'foo': [{'c': 43}, {1: 55}]}
Then tell it to sort by the value:
>>> x={'foo': [{1: 55}, {'c': 43}], 'bar': [{1: 43}, {'c': 40}]}
>>> for a in x: x[a].sort(key=lambda i: list(i.values())[0])
>>> x
{'bar': [{'c': 40}, {1: 43}], 'foo': [{'c': 43}, {1: 55}]}
Note since it's a dict, you have to retrieve all values, convert to list, and take first index. Probably not the best sturcture to sort.
As an alternative to kabanus' answer (which uses O(len(x)) dict lookup), this is an approach that use dict values view:
x={'a': [{1: 55}, {'c': 43}], 'b': [{1: 43}, {'c': 40}]}
for a in x.values(): a.sort(key=lambda i: list(i.values())[0])
print(x)
prints
{'a': [{'c': 43}, {1: 55}], 'b': [{'c': 40}, {1: 43}]}
Try it online!
I have not measured the performance of this method, but I expect it would be faster.
You can simply do:
data={'foo': [{1: 55}, {'c': 43}], 'bar': [{1: 43}, {'c': 40}]}
print({i:sorted(j,key=lambda x:list(x.values())) for i,j in data.items()})
output:
{'foo': [{'c': 43}, {1: 55}], 'bar': [{'c': 40}, {1: 43}]}

How convert list of dictionaries to a dictionary of dictionaries in Python [duplicate]

This question already has answers here:
how to convert list of dict to dict
(9 answers)
Closed 1 year ago.
I am trying to merge in just one dictionary a group of dictionaries, following the example.
I have a list of dictionaries:
dict_list = [ {'key1':1, 'key2': 2, ...}, {'key1':1, 'key2': 2, ...}, {'key1':1, 'key2': 2, ...} ... ]
And I would like to convert it to:
dictonary = { {'key1':1, 'key2':2, ...}, {'key1':1, 'key2':2, ...}, {'key1':1, 'key2':2, ...} ... }
Does anyone know if it's possible?
You could change the keys to whatever you want but as an example you could do
dict_list = [ {'key1':1, 'key2': 2}, {'key1':1, 'key2': 2}, {'key1':1, 'key2': 2}]
dictionary = {}
for i, d in enumerate(dict_list):
dictionary[i] = d
{0: {'key2': 2, 'key1': 1}, 1: {'key2': 2, 'key1': 1}, 2: {'key2': 2, 'key1': 1}}
As a note this isn't very useful since you can just search your list by index which is the same syntax as getting your value based off your key. The only way it would be different is if your keys weren't based off something like peoples names
print dictionary[0]
{'key2': 2, 'key1': 1}
print dict_list[0]
{'key2': 2, 'key1': 1}

Pythonic sort a list of dictionaries in a tricky order

I have a list of id's sorted in a proper oder:
ids = [1, 2, 4, 6, 5, 0, 3]
I also have a list of dictionaries, sorted in some random way:
rez = [{'val': 7, 'id': 1}, {'val': 8, 'id': 2}, {'val': 2, 'id': 3}, {'val': 0, 'id': 4}, {'val': -1, 'id': 5}, {'val': -4, 'id': 6}, {'val': 9, 'id': 0}]
My intention is to sort rez list in a way that corresponds to ids:
rez = [{'val': 7, 'id': 1}, {'val': 8, 'id': 2}, {'val': 0, 'id': 4}, {'val': -4, 'id': 6}, {'val': -1, 'id': 5}, {'val': 9, 'id': 0}, {'val': 2, 'id': 3}]
I tried:
rez.sort(key = lambda x: ids.index(x['id']))
However that way is too slow for me, as len(ids) > 150K, and each dict actually had a lot of keys (some values there are strings). Any suggestion how to do it in the most pythonic, but still fastest way?
You don't need to sort because ids specifies the entire ordering of the result. You just need to pick the correct elements by their ids:
rez_dict = {d['id']:d for d in rez}
rez_ordered = [rez_dict[id] for id in ids]
Which gives:
>>> rez_ordered
[{'id': 1, 'val': 7}, {'id': 2, 'val': 8}, {'id': 4, 'val': 0}, {'id': 6, 'val': -4}, {'id': 5, 'val': -1}, {'id': 0, 'val': 9}, {'id': 3, 'val': 2}]
This should be faster than sorting because it can be done in linear time on average, while sort is O(nlogn).
Note that this assumes that there will be one entry per id, as in your example.
I think you are on the right track. If you need to speed it up, because your list is too long and you are having quadratic complexity, you can turn the list into a dictionary first, mapping the ids to their respective indices.
indices = {id_: pos for pos, id_ in enumerate(ids)}
rez.sort(key = lambda x: indices[x['id']])
This way, indices is {0: 5, 1: 0, 2: 1, 3: 6, 4: 2, 5: 4, 6: 3}, and rez is
[{'id': 1, 'val': 7},
{'id': 2, 'val': 8},
{'id': 4, 'val': 0},
{'id': 6, 'val': -4},
{'id': 5, 'val': -1},
{'id': 0, 'val': 9},
{'id': 3, 'val': 2}]

Categories

Resources