Remove the duplicate from list of dict in python - python

I have dict like this
d=[{'a':1,'b':2},{'a':2,'b':2},{'a':3},{'a':1}]
So i need like
d=[{'a':1,'b':2},{'a':2,'b':2},{'a':3}]
Remove duplicate

Learn more about Python data types and theirs functions. Here is one tutorial for dictionaries
As what I know using list of dictionaries is a bad practice
Here is my solution it could be not so elegant, but it is working. Also remove duplicates means remove ALL of them, so I remove all list elements where they were repeated.
d = [{'a': 1, 'b': 2}, {'a': 2, 'b': 2}, {'a': 3}, {'a': 1}]
temp = []
for i in d:
for x, y in i.items():
temp_var = [x, y]
if temp_var in temp:
d.pop(d.index(i))
else:
temp.append(temp_var)
print(d)
# result [{'a': 1, 'b': 2}, {'a': 3}]
P.S.: Keep learning and have a nice day :)

Related

how to add same dictionary to a list with modified value

csv={“a”:0}
list_=[]
for i in range(2):
csv["a"]+=1
list_.append(csv)
print(list_,csv)
I am getting output like this:
[{'a': 2}, {'a': 2}]
I need to get an output like this
[{'a': 1}, {'a': 2}]
Because python pass variables to functions as reference and not as value, you need to pass a copy of the original dictionnary to list_.append():
csv={"a":0}
list_=[]
for i in range(2):
csv["a"]+=1
list_.append(dict(csv))
print(list_)
You can do a list-comprehension:
list_ = [{'a': x} for x in range(1, 3)]
# [{'a': 1}, {'a': 2}]

Sorting identical keys in a dictionary [duplicate]

This question already has answers here:
How can one make a dictionary with duplicate keys in Python?
(9 answers)
Closed 6 years ago.
I just started learning python and was wondering if its possible to pair two identical keys?
example:
my_dict= {1:a,3:b,1:c}
and I want to make a new dict, something like this:
new_dict= {1:{a,c},3:{b}}
thanks for the help
You can't have identical keys, that is the definition of dictionary. As soon as you add again the same key, the previous entry is deleted
You cannot have repeated dictionary keys in python.
From what I understand, you're trying to combine the two dictionaries. Given that you cannot have same keys in a dictionary, I'll suppose you have two distinct dictionaries you'd like to combine to obtain your combination.
Ex:
dic1 = {'a': 1, 'b': 2, 'c': 3}
dic2 = {'c': 4, 'd': 5, 'e': 6}
And the combination would produce:
{'a': {1}, 'b': {2}, 'c':{3, 4}, 'd': {4}, 'e': {6}}
You could use this Example:
from itertools import chain
from collections import defaultdict
dic1 = {'A': 1, 'B': 2, 'C': 3}
dic2 = {'C': 4, 'D': 5, 'E': 6}
dic = defaultdict(set)
for k, v in chain(dic1.items(), dic2.items()):
dic[k].add(v)
print(dict(dic))
Something to note:
'dic' is not exactly a dict(), it's of type 'defaultdict', but you can do dict(dic) to make it so.
You could instead of using set, use list in the defaultdict() argument and have a dictionary as so:
{'a': [1], 'b': [2], 'c':[3, 4], 'd': [4], 'e': [6]}
But to do so, dic[k].append(v) would be used in the for loop. You add items to sets, append to lists.
Dictionaries in Python, or any hash-able type for that matter, will not allow duplicate keys. If two duplicate keys are found in a dictionary, the key farthest in the dictionary will be persevered. This behavior can be obsevered first hand:
>>> my_dict= {1:'a',3:'b',1:'c'}
>>> my_dict
{1: 'c', 3: 'b'}
>>> my_dict= {1:'c',3:'b',1:'a'}
>>> my_dict
{1: 'a', 3: 'b'}
>>>
The Python documentation for dict()s touches on this matter:
It is best to think of a dictionary as an unordered set of key: value pairs, with the requirement that the keys are unique (within one dictionary).[...].
(emphasis mine)

Pythonic way of finding duplicate maps in a list while ignoring certain keys, and combining the duplicate maps to make a new list

I want to write a code which takes the following inputs:
list (list of maps)
request_keys (list of strings)
operation (add,substract,multiply,concat)
The code would look at the list for the maps having the same value for all keys except the keys given in request_keys. Upon finding two maps for which the value in the search keys match, the code would do the operation (add,multiple,substract,concat) on the two maps and combine them into one map. This combination map would basically replace the other two maps.
i have written the following peice of code to do this. The code only does add operation. It can be extended to make the other operations
In [83]: list
Out[83]:
[{'a': 2, 'b': 3, 'c': 10},
{'a': 2, 'b': 3, 'c': 3},
{'a': 2, 'b': 4, 'c': 4},
{'a': 2, 'b': 3, 'c': 2},
{'a': 2, 'b': 3, 'c': 3}]
In [84]: %cpaste
Pasting code; enter '--' alone on the line to stop or use Ctrl-D.
:def func(list,request_keys):
: new_list = []
: found_indexes = []
: for i in range(0,len(list)):
: new_item = list[i]
: if i in found_indexes:
: continue
: for j in range(0,len(list)):
: if i != j and {k: v for k,v in list[i].iteritems() if k not in request_keys} == {k: v for k,v in list[j].iteritems() if k not in request_keys}:
: found_indexes.append(j)
: for request_key in request_keys:
: new_item[request_key] += list[j][request_key]
: new_list.append(new_item)
: return new_list
:--
In [85]: func(list,['c'])
Out[85]: [{'a': 2, 'b': 3, 'c': 18}, {'a': 2, 'b': 4, 'c': 4}]
In [86]:
What i want to know is, is there a faster, more memory efficient, cleaner and a more pythonic way of doing the same?
Thank you
You manually generate all the combinations and then compare each of those combinations. This is pretty wasteful. Instead, I suggest grouping the dictionaries in another dictionary by their matching keys, then adding the "same" dictionaries. Also, you forgot the operator parameter.
import collections, operator, functools
def func(lst, request_keys, op=operator.add):
matching_dicts = collections.defaultdict(list)
for d in lst:
key = tuple(sorted(((k, d[k]) for k in d if k not in request_keys)))
matching_dicts[key].append(d)
for group in matching_dicts.values():
merged = dict(group[0])
merged.update({key: functools.reduce(op, (g[key] for g in group))
for key in request_keys})
yield merged
What this does: First, it creates a dictionary, mapping the key-value pairs that have to be equal for two dictionaries to match to all those dictionaries that have those key-value pairs. Then it iterates the dicts from those groups, using one of that group as a prototype and updating it with the sum (or product, or whatever, depending on the operator) of the all the dicts in that group for the required_keys.
Note that this returns a generator. If you want a list, just call it like list(func(...)), or accumulate the merged dicts in a list and return that list.
from itertools import groupby
from operator import itemgetter
def mergeDic(inputData, request_keys):
keys = inputData[0].keys()
comparedKeys = [item for item in keys if item not in request_keys]
grouper = itemgetter(*comparedKeys)
result = []
for key, grp in groupby(sorted(inputData, key = grouper), grouper):
temp_dict = dict(zip(comparedKeys, key))
for request_key in request_keys:
temp_dict[request_key] = sum(item[request_key] for item in grp)
result.append(temp_dict)
return result
inputData = [{'a': 2, 'b': 3, 'c': 10},
{'a': 2, 'b': 3, 'c': 3},
{'a': 2, 'b': 4, 'c': 4},
{'a': 2, 'b': 3, 'c': 2},
{'a': 2, 'b': 3, 'c': 3}]
from pprint import pprint
pprint(mergeDic(inputData,['c']))

Python adding dictionary values with same key within a list

i just picked up python not too long ago.
An example below
i have a dictionary within a list
myword = [{'a': 2},{'b':3},{'c':4},{'a':1}]
I need to change it to the output below
[{'a':3} , {'b':3} , {'c':4}]
is there a way where i can add the value together? I tried using counter, but it prints out the each dict out.
what i did using Counter:
for i in range(1,4,1):
text = myword[i]
Print Counter(text)
The output
Counter({'a': 2})
Counter({'b': 3})
Counter({'c': 4})
Counter({'a': 1})
i have read the link below but what they compared was between 2 dict.
Is there a better way to compare dictionary values
Thanks!
Merge dictionaries into one dictionary (Counter), and split them.
>>> from collections import Counter
>>> myword = [{'a': 2}, {'b':3}, {'c':4}, {'a':1}]
>>> c = Counter()
>>> for d in myword:
... c.update(d)
...
>>> [{key: value} for key, value in c.items()]
[{'a': 3}, {'c': 4}, {'b': 3}]
>>> [{key: value} for key, value in sorted(c.items())]
[{'a': 3}, {'b': 3}, {'c': 4}]

How to access key in Python dictionary

I know it's possible to traverse a dictionary by using iteritems() or keys(). But what if I got a list of dics such as: l = [{'a': 1}, {'b': 2}, {'c': 3}] and I want to compose a string using its keys, e.g., s = 'a, b, c'?
One solution is to copy all the keys into a list in advance, and compose the string I want. Just wondering if there is a better solution.
You can use itertools.chain() for it and make use of the fact that iterating over a dict will yield its keys.
import itertools
lst = [{'a': 1}, {'b': 2}, {'c': 3}]
print ', '.join(itertools.chain(*lst))
This also works it there are dicts with more than one element.
If you do not want duplicate elements, use a set:
print ', '.join(set(itertools.chain(*lst)))
Assuming each dictionary will only have a single key:
', '.join(a.keys()[0] for a in l)
if not, maybe something like:
>>> l = [{'a': 1, 'd': 4}, {'b': 2}, {'c': 3}]
>>> ', '.join(', '.join(a.keys()) for a in l)
'a, d, b, c'
Iterate over the dictionaries and then over the keys of each dictionary:
>>> lst = [{'a': 1}, {'b': 2}, {'c': 3}]
>>> ', '.join(key for dct in lst for key in dct.keys())
'a, b, c'
Try this:
''.join([i.keys()[0] for i in l])
You can put any delimiter you want inside of the quotes. Just bear in mind that the dictionary isn't ordered, so you may get weird looking strings as a result of this.

Categories