comparing dicts with additional values - python

I have 2 lists of python dicts: realList and expectedList
I want realList to be considered equal to expectedList if there is one, and only one, "sub-dict" on realList for each dict of expectedList
By sub-dict I mean a dict with at least the same key/values, but which might have additional key/values.
so, for example:
realDict = [{'a': 1, 'b': 2}, {'a': 2, 'b': 3}]
==
expectedDict = [{'a': 1}, {'a': 2, 'b': 3}]
realDict = [{'a': 1, 'b': 2}, {'a': 2, 'b': 3}]
!=
expectedDict = [{'a': 2}, {'a': 2, 'b': 3}]
realDict = [{'a': 1, 'b': 2}, {'a': 1, 'b': 3}]
!=
expectedDict = [{'a': 1}]
Any modules to help? Only idea I can think of is iterating over expectedDict and removing a dict from it and from realDict whenever they match. Then, in the end, both must be [].

This works, but I'm unsure how performant it is:
def complete_subset(real_list, expected_list):
real_set_list = [set(d.items()) for d in real_list]
expected_set_list = [set(d.items()) for d in expected_list]
while len(real_set_list):
real_len = len(real_set_list)
i = 0
for real_set in real_set_list:
for expected_set in expected_set_list:
if not len(expected_set - real_set):
real_set_list.remove(real_set)
expected_set_list.remove(expected_set)
i = i + 1
if i == real_len:
break
return (not len(real_set_list)) and (not len(expected_set_list))
Here are my tests:
print complete_subset([{'a': 1, 'b': 2}, {'a': 2, 'b': 3}], [{'a': 1}, {'a': 2, 'b': 3}]) == True
print complete_subset([{'a': 1, 'b': 2}, {'a': 2, 'b': 3}], [{'a': 2}, {'a': 2, 'b': 3}]) == False
print complete_subset([{'a': 1, 'b': 2}, {'a': 2, 'b': 3}], [{'a': 1}]) == False
print complete_subset([{'a': 1, 'b': 2}, {'a': 1, 'b': 2}], [{'a': 1}, {'b': 2}]) == True
print complete_subset([
{'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 6, 'g': 7, 'h': 8, 'i': 9, 'j': 10},
{'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 6, 'g': 7, 'h': 8, 'i': 9, 'j': 10},
{'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 6, 'g': 7, 'h': 8, 'i': 9, 'j': 10},
{'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 6, 'g': 7, 'h': 8, 'i': 9, 'j': 10},
{'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 6, 'g': 7, 'h': 8, 'i': 9, 'j': 10},
{'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 6, 'g': 7, 'h': 8, 'i': 9, 'j': 10},
{'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 6, 'g': 7, 'h': 8, 'i': 9, 'j': 10},
{'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 6, 'g': 7, 'h': 8, 'i': 9, 'j': 10},
{'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 6, 'g': 7, 'h': 8, 'i': 9, 'j': 10},
{'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 6, 'g': 7, 'h': 8, 'i': 9, 'j': 10},
{'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 6, 'g': 7, 'h': 8, 'i': 9, 'j': 10},
{'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 6, 'g': 7, 'h': 8, 'i': 9, 'j': 10},
], [
{'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 6, 'g': 7, 'h': 8, 'i': 9},
{'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 6, 'g': 7, 'h': 8},
{'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 6, 'g': 7},
{'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 6},
{'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5},
{'a': 1, 'b': 2, 'c': 3, 'd': 4},
{'a': 1, 'b': 2, 'c': 3},
{'a': 1, 'b': 2},
{'a': 1},
{'a': 1, 'c': 3, 'd': 4, 'f': 6, 'g': 7, 'h': 8, 'i': 9, 'j': 10},
{'a': 1, 'b': 2, 'c': 3, 'e': 5, 'f': 6, 'h': 8, 'i': 9, 'j': 10},
{'a': 1, 'b': 2, 'd': 4, 'e': 5, 'g': 7, 'h': 8, 'j': 10},
]) == True

In case your two lists are to be compared element by element, you can do it this way.
def compare(realDict, expectedDict):
if len(readDict) != len(expectedDict):
return False
for d1, d2 in zip(realDict, expectedDict):
for key in d2:
if key not in d1 or d1[key] != d2[key]:
return False
return True

Related

Merging two or more dictionaries when they have the same key value pairs [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
Improve this question
I am trying to merge two or more dictionaries in a list to combine them using same set of key value pairs. If the specified key value pairs exists, then merge the other keys for those dictionaries gets added under 'other_cols'. Below is what my input looks like and what I am expecting as an output.
input_list = [{'a': 1, 'b' : 2, 'c': 3, 'd': 4},
{'a': 1, 'b' : 2, 'c': 5, 'd': 6},
{'a': 9, 'b' : 10, 'c': 11, 'd': 12},
{'a': 9, 'b' : 10, 'c': 13, 'd': 14},
{'a': 9, 'b' : 10, 'c': 15, 'd': 16},
{'a': 17, 'b' : 18, 'c': 19, 'd': 20},
{'a': 1, 'b' : 2, 'c': 7, 'd': 8}]
merge_by_keys = ['a','b']
expected_output_list = [{'a': 1, 'b' : 2, 'other_cols':[{'c': 3, 'd': 4},
{'c': 5, 'd': 6},
{'c': 7, 'd': 8}],
{'a': 9, 'b' : 10, 'other_cols':[{'c': 11, 'd': 12},
{'c': 13, 'd': 14},
{'c': 15, 'd': 16}],
{'a': 17, 'b' : 18, 'other_cols':[{'c': 19, 'd': 20}]}
This looks like what you are looking for:
The most interesting line is:
out[tuple((entry[x],x) for x in merge_by_keys)].append({k: v for k, v in entry.items() if k not in merge_by_keys})
Make sure you understand it. Ask if you have questions.
from collections import defaultdict
data = [{'a': 1, 'b': 2, 'c': 3, 'd': 4},
{'a': 1, 'b': 2, 'c': 5, 'd': 6},
{'a': 9, 'b': 10, 'c': 11, 'd': 12},
{'a': 9, 'b': 10, 'c': 13, 'd': 14},
{'a': 9, 'b': 10, 'c': 15, 'd': 16},
{'a': 17, 'b': 18, 'c': 19, 'd': 20},
{'a': 1, 'b': 2, 'c': 7, 'd': 8}]
merge_by_keys = ['a', 'b']
out = defaultdict(list)
for entry in data:
out[tuple((entry[x],x) for x in merge_by_keys)].append({k: v for k, v in entry.items() if k not in merge_by_keys})
result = []
for k, v in out.items():
result.append({})
for x in k:
result[-1][x[1]] = x[0]
result[-1]['other'] = v
for entry in result:
print(entry)
output
{'a': 1, 'b': 2, 'other': [{'c': 3, 'd': 4}, {'c': 5, 'd': 6}, {'c': 7, 'd': 8}]}
{'a': 9, 'b': 10, 'other': [{'c': 11, 'd': 12}, {'c': 13, 'd': 14}, {'c': 15, 'd': 16}]}
{'a': 17, 'b': 18, 'other': [{'c': 19, 'd': 20}]}
here's one way to do it using a dictionary to group entries and turning its values into a list at the end.
input_list = [{'a': 1, 'b' : 2, 'c': 3, 'd': 4},
{'a': 1, 'b' : 2, 'c': 5, 'd': 6},
{'a': 9, 'b' : 10, 'c': 11, 'd': 12},
{'a': 9, 'b' : 10, 'c': 13, 'd': 14},
{'a': 9, 'b' : 10, 'c': 15, 'd': 16},
{'a': 17, 'b' : 18, 'c': 19, 'd': 20},
{'a': 1, 'b' : 2, 'c': 7, 'd': 8}]
merge_keys = ['a','b']
grouped = dict()
for d in input_list:
groupKey = tuple(map(d.get,merge_keys))
groupDict = grouped.setdefault(groupKey,{k:d.pop(k) for k in merge_keys})
groupDict.setdefault('other_cols',[]).append(d)
result = list(grouped.values())
print(result)
[{'a': 1, 'b': 2, 'other_cols': [{'c': 3, 'd': 4},
{'c': 5, 'd': 6},
{'c': 7, 'd': 8}]},
{'a': 9, 'b': 10, 'other_cols': [{'c': 11, 'd': 12},
{'c': 13, 'd': 14},
{'c': 15, 'd': 16}]},
{'a': 17, 'b': 18, 'other_cols': [{'c': 19, 'd': 20}]}]

Concatenate n-values of dictionary to create a new value for a list in Python

I want to create a new value for a new list from n-concatenated values of a dictionary, as strange as it sounds I want something as described below.
I have a dictionary like this:
{'A': 9, 'B': 1, 'C': 2, 'D': 7, 'E': 6, 'F': 8, 'G': 5, 'H': 3, 'I': 4}
{'A': 9, 'B': 1, 'C': 2, 'D': 5, 'E': 3, 'F': 4, 'G': 7, 'H': 6, 'I': 8}
{'A': 7, 'B': 6, 'C': 8, 'D': 9, 'E': 1, 'F': 2, 'G': 5, 'H': 3, 'I': 4}
{'A': 7, 'B': 6, 'C': 8, 'D': 5, 'E': 3, 'F': 4, 'G': 9, 'H': 1, 'I': 2}
{'A': 5, 'B': 3, 'C': 4, 'D': 7, 'E': 6, 'F': 8, 'G': 9, 'H': 1, 'I': 2}
{'A': 5, 'B': 3, 'C': 4, 'D': 9, 'E': 1, 'F': 2, 'G': 7, 'H': 6, 'I': 8}
and I want the result as a new list, for example my_list[0] = ABC values , my_list[1] = DEF values and so on which will be displayed as 912, 768, 534 for the first row of my dictionary. The sorting does matter, it must remain as it is.
I am new to Python 3.x and I cannot find something similar to this problem. All I have achieved is to print the values only, one after another with the below script:
res_list = {frozenset(item.items()) : item for item in my_dictionary}.values()
for x in solutions:
for elem in x.keys():
print(x[elem])
Can I iterate the values and concat them per 3 steps? My goal here is to create a list of 3 digit numbers and compare these values for duplicates so that the result will be in my case just 3 distinct numbers that the sorting here does not matter.
912, 768, 345
I understand that your question may be schematic and so your dictionary keys may not actually be 'A', 'B', 'C' etc.
But given that proviso, does this help?
>>> mydict = {'A': 9, 'B': 1, 'C': 2, 'D': 7, 'E': 6, 'F': 8, 'G': 5, 'H': 3, 'I': 4}
>>> mylist = [int(''.join(str(mydict[k]) for k in group)) for group in ('ABC','DEF','GHI')]
>>> mylist
[912, 768, 534]

removing keys and values from a nested dictionary

I'm relatively new to programming and I'm quite stuck.
I have a dictionary like this below. I want to say like
n = "a"
then I want to remove every variable n from the dictionary.
Then I want to remove every letter a that is in this nested dictionary below. I know how to remove stuff from dictionaries to a tiny extent, but I'm quite confused right now as I don't know how to do it with a nested dictionary. In this case, there's a key and then a value but inside the value is another dictionary with other keys and values. I have implemented for loops etc. to try and do what I want to do but the solution I get isn't what I'm looking for.
Thank you:)
{'b': {'a': 7, 'c': 10, 'd': 15}, 'a': {'b': 7, 'c': 9, 'f': 14}, 'c': {'a': 9, 'b': 10, 'd': 11, 'f': 2}, 'f': {'a': 14, 'c': 2, 'e': 9}, 'd': {'b': 15, 'c': 11, 'e': 6}, 'e': {'d': 6, 'f': 9}}
dic = {'b': {'a': 7, 'c': 10, 'd': 15}, 'a': {'b': 7, 'c': 9, 'f': 14}, 'c': {'a': 9, 'b': 10, 'd': 11, 'f': 2}, 'f': {'a': 14, 'c': 2, 'e': 9}, 'd': {'b': 15, 'c': 11, 'e': 6}, 'e': {'d': 6, 'f': 9}}
This is what I have so far, but it's just removing the first b which is a key, how do i access the b's inside the nested dictionary
n = "b"
del dic[n]
print(dic)
and whenever I do something like :
dic = {'b': {'a': 7, 'c': 10, 'd': 15}, 'a': {'b': 7, 'c': 9, 'f': 14}, 'c': {'a': 9, 'b': 10, 'd': 11, 'f': 2}, 'f': {'a': 14, 'c': 2, 'e': 9}, 'd': {'b': 15, 'c': 11, 'e': 6}, 'e': {'d': 6, 'f': 9}}
and whenever I do something like:
n = "b"
for k in dic.keys():
if k == n:
del dic[k]
it comes up in the terminal that RuntimeError: dictionary changed size during iteration
You could write a recursive function:
def delete_key(k, dic):
if k in dic:
del dic[k]
for val in dic.values():
if isinstance(val, dict):
delete_key(k, val)
return dic
d = {'b': {'a': 7, 'c': 10, 'd': 15}, 'a': {'b': 7, 'c': 9, 'f': 14}, 'c': {'a': 9, 'b': 10, 'd': 11, 'f': 2}, 'f': {'a': 14, 'c': 2, 'e': 9}, 'd': {'b': 15, 'c': 11, 'e': 6}, 'e': {'d': 6, 'f': 9}}
delete_key('b', d)
{'a': {'c': 9, 'f': 14},
'c': {'a': 9, 'd': 11, 'f': 2},
'd': {'c': 11, 'e': 6},
'e': {'d': 6, 'f': 9},
'f': {'a': 14, 'c': 2, 'e': 9}}
Assuming you want to convert the dictionary to a matrix, you can do this as follows:
from sklearn.feature_extraction import DictVectorizer
dictionary = {
'b': {'a': 7, 'c': 10, 'd': 15},
'a': {'b': 7, 'c': 9, 'f': 14},
'c': {'a': 9, 'b': 10, 'd': 11, 'f': 2},
'f': {'a': 14, 'c': 2, 'e': 9},
'd': {'b': 15, 'c': 11, 'e': 6},
'e': {'d': 6, 'f': 9}
}
keys_removed = [dictionary.get(i) for i in dictionary]
dictvectorizer = DictVectorizer(sparse=False)
matrix = dictvectorizer.fit_transform(keys_removed)
This will provide the following output:
[[ 7. 0. 10. 15. 0. 0.]
[ 0. 7. 9. 0. 0. 14.]
[ 9. 10. 0. 11. 0. 2.]
[14. 0. 2. 0. 9. 0.]
[ 0. 15. 11. 0. 6. 0.]
[ 0. 0. 0. 6. 0. 9.]]
With matrix indices corresponding to the inner key values (a to f), which is why the matrix has zeroes where a value does not exist at a specific key.
Alternatively, if you just want to get rid of the main keys, you simply need to use keys_removed = [dictionary.get(i) for i in dictionary] and convert it from a list.
This will give you the following:
[{'a': 7, 'c': 10, 'd': 15}, {'b': 7, 'c': 9, 'f': 14}, {'a': 9, 'b': 10, 'd': 11, 'f': 2}, {'a': 14, 'c': 2, 'e': 9}, {'b': 15, 'c': 11, 'e': 6}, {'d': 6, 'f': 9}]
EDIT
If you want to delete certain keys and their corresponding entries, you could do something like this:
def delete_key(keys: list):
dictionary = {
'b': {'a': 7, 'c': 10, 'd': 15},
'a': {'b': 7, 'c': 9, 'f': 14},
'c': {'a': 9, 'b': 10, 'd': 11, 'f': 2},
'f': {'a': 14, 'c': 2, 'e': 9},
'd': {'b': 15, 'c': 11, 'e': 6},
'e': {'d': 6, 'f': 9}
}
for i in keys:
dictionary.pop(i)
return dictionary
print (delete_key(keys=['a', 'c']))
This takes a list of keys that you want to delete and returns a new dictionary without them. The above case outputs:
{'b': {'a': 7, 'c': 10, 'd': 15}, 'f': {'a': 14, 'c': 2, 'e': 9}, 'd': {'b': 15, 'c': 11, 'e': 6}, 'e': {'d': 6, 'f': 9}}
According to your recent clarifications, this should work:
def delete_key(outer_keys: list, inner_keys: list):
dictionary = {
'b': {'a': 7, 'c': 10, 'd': 15},
'a': {'b': 7, 'c': 9, 'f': 14},
'c': {'a': 9, 'b': 10, 'd': 11, 'f': 2},
'f': {'a': 14, 'c': 2, 'e': 9},
'd': {'b': 15, 'c': 11, 'e': 6},
'e': {'d': 6, 'f': 9}
}
for i in outer_keys:
dictionary.pop(i)
for i in dictionary:
for j in inner_keys:
if j in dictionary[i]:
dictionary[i].pop(j)
return dictionary
print (delete_key(outer_keys=[], inner_keys=['a']))
The function works as follows:
It allows you to specify which keys (and corresponding entries) you want removed. You simply list which in either outer_keys or inner_keys, the latter being the deepest keys in the nested dictionary.
These have to be defined as a list of the key names and can be empty if you want to only remove the keys from the inner or outer.
The above example will output the following:
{'b': {'c': 10, 'd': 15}, 'a': {'b': 7, 'c': 9, 'f': 14}, 'c': {'b': 10, 'd': 11, 'f': 2}, 'f': {'c': 2, 'e': 9}, 'd': {'b': 15, 'c': 11, 'e': 6}, 'e': {'d': 6, 'f': 9}}
You will notice that all of the inner 'a' keys have been removed. The operation can be done using fewer loops, but this should illustrate the process well enough.

Vowel count for each line of txt file

Trying to count the number of vowels in each line of a text file. So far I have the following;
lc=0
lst=[]
vowel_count={}
with open('frankenstein.txt', 'r') as f:
for line in f:
no_of_characters=len(line)
l1=line.lower()
lc+=1
if no_of_characters !=1:
for vowel in "aeiou":
count=l1.count(vowel)
vowel_count[vowel]=count
print(lc, vowel_count)
print(lc, vowel_count)
I want the output to display the number of vowels and the corresponding line number, which is the purpose of the "lc" variable.
However when the code runs it gives the following output;
2128 {'a': 2, 'e': 6, 'i': 0, 'o': 0, 'u': 1}
2128 {'a': 2, 'e': 6, 'i': 5, 'o': 0, 'u': 1}
2128 {'a': 2, 'e': 6, 'i': 5, 'o': 4, 'u': 1}
2128 {'a': 2, 'e': 6, 'i': 5, 'o': 4, 'u': 3}
2129 {'a': 3, 'e': 6, 'i': 5, 'o': 4, 'u': 3}
2129 {'a': 3, 'e': 6, 'i': 5, 'o': 4, 'u': 3}
2129 {'a': 3, 'e': 6, 'i': 4, 'o': 4, 'u': 3}
2129 {'a': 3, 'e': 6, 'i': 4, 'o': 6, 'u': 3}
2129 {'a': 3, 'e': 6, 'i': 4, 'o': 6, 'u': 2}
2130 {'a': 3, 'e': 6, 'i': 4, 'o': 6, 'u': 2}
2130 {'a': 3, 'e': 5, 'i': 4, 'o': 6, 'u': 2}
2130 {'a': 3, 'e': 5, 'i': 2, 'o': 6, 'u': 2}
2130 {'a': 3, 'e': 5, 'i': 2, 'o': 10, 'u': 2}
2130 {'a': 3, 'e': 5, 'i': 2, 'o': 10, 'u': 3}
2131 {'a': 3, 'e': 5, 'i': 2, 'o': 10, 'u': 3}
2131 {'a': 3, 'e': 8, 'i': 2, 'o': 10, 'u': 3}
2131 {'a': 3, 'e': 8, 'i': 2, 'o': 10, 'u': 3}
2131 {'a': 3, 'e': 8, 'i': 2, 'o': 6, 'u': 3}
2131 {'a': 3, 'e': 8, 'i': 2, 'o': 6, 'u': 3}
2132 {'a': 3, 'e': 8, 'i': 2, 'o': 6, 'u': 3}
I get get several outputs for each line, how do i stop this?
You're printing status after each new found vowel. Move your print out of the inner for loop.

Remove duplicate dicts from list based on uniqueness of keys

My question is somewhat similar to this question: https://codereview.stackexchange.com/questions/175079/removing-key-value-pairs-in-list-of-dicts. Essentially, I have a list of dictionaries, and I want to remove duplicates from the list based on the unique combination of two (or more) keys within each dictionary.
Suppose I have the following list of dictionaries:
some_list_of_dicts = [
{'a': 1, 'b': 1, 'c': 1, 'd': 2, 'e': 4},
{'a': 1, 'b': 1, 'c': 1, 'd': 5, 'e': 1},
{'a': 1, 'b': 1, 'c': 1, 'd': 7, 'e': 8},
{'a': 1, 'b': 1, 'c': 1, 'd': 9, 'e': 6},
{'a': 1, 'b': 1, 'c': 2, 'd': 2, 'e': 3},
{'a': 1, 'b': 1, 'c': 3, 'd': 2, 'e': 3},
{'a': 1, 'b': 1, 'c': 4, 'd': 2, 'e': 3}
]
And let's suppose the combination of a, b, and c have to be unique; any other values can be whatever they want, but the combination of these three must be unique to this list. I would want to take whichever unique combo of a, b, and c came first, keep that, and discard everything else where that combination is the same.
The new list, after running it through some remove_duplicates function would look like this:
new_list = [
{'a': 1, 'b': 1, 'c': 1, 'd': 2, 'e': 4},
{'a': 1, 'b': 1, 'c': 2, 'd': 2, 'e': 3},
{'a': 1, 'b': 1, 'c': 3, 'd': 2, 'e': 3},
{'a': 1, 'b': 1, 'c': 4, 'd': 2, 'e': 3}
]
I've only managed to come up with this:
def remove_duplicates(old_list):
uniqueness_check_list = []
new_list = []
for item in old_list:
# The unique combination is 'a', 'b', and 'c'
uniqueness_check = "{}{}{}".format(
item["a"], item["b"], item["c"]
)
if uniqueness_check not in uniqueness_check_list:
new_list.append(item)
uniqueness_check_list.append(uniqueness_check)
return new_list
But this doesn't feel very Pythonic. It also has the problem that I've hardcoded in the function which keys have to be unique; it would be better if I could specify that as an argument to the function itself, but again, not sure what's the most elegant way to do this.
You can use a dict comprehension to construct a dict from the list of dicts in the reversed order so that the values of the first of any unique combinations would take precedence. Use operator.itemgetter to get the unique keys as a tuple. Reverse again in the end for the original order:
from operator import itemgetter
list({itemgetter('a', 'b', 'c')(d): d for d in reversed(some_list_of_dicts)}.values())[::-1]
This returns:
[{'a': 1, 'b': 1, 'c': 1, 'd': 2, 'e': 4},
{'a': 1, 'b': 1, 'c': 2, 'd': 2, 'e': 3},
{'a': 1, 'b': 1, 'c': 3, 'd': 2, 'e': 3},
{'a': 1, 'b': 1, 'c': 4, 'd': 2, 'e': 3}]
With the help of a function to keep track of duplicates, you can use some list comprehension:
def remove_duplicates(old_list, cols=('a', 'b', 'c')):
duplicates = set()
def is_duplicate(item):
duplicate = item in duplicates
duplicates.add(item)
return duplicate
return [x for x in old_list if not is_duplicate(tuple([x[col] for col in cols]))]
To use:
>>> remove_duplicates(some_list_of_dicts)
[
{'a': 1, 'c': 1, 'b': 1, 'e': 4, 'd': 2},
{'a': 1, 'c': 2, 'b': 1, 'e': 3, 'd': 2},
{'a': 1, 'c': 3, 'b': 1, 'e': 3, 'd': 2},
{'a': 1, 'c': 4, 'b': 1, 'e': 3, 'd': 2}
]
You can also provide different columns to key on:
>>> remove_duplicates(some_list_of_dicts, cols=('a', 'd'))
[
{'a': 1, 'c': 1, 'b': 1, 'e': 4, 'd': 2},
{'a': 1, 'c': 1, 'b': 1, 'e': 1, 'd': 5},
{'a': 1, 'c': 1, 'b': 1, 'e': 8, 'd': 7},
{'a': 1, 'c': 1, 'b': 1, 'e': 6, 'd': 9}
]

Categories

Resources