Removing duplicate values in Python dictionaries? [duplicate] - python

This question already has answers here:
Removing Duplicates From Dictionary
(11 answers)
remove duplicates values in a dictionary python
(1 answer)
Closed 2 years ago.
More a concept question than a direct coding one. But say I had a dictionary akin to this one.
Dict = {'A':1, 'B':3, 'C':3, 'D':4, 'E':1}
Dict2 = {}
And I wanted to take all instances were two keys had the same value, and put them in a different dictionary, what sort of process be the most efficient? I've tried measures like
for value in Dict.items()
for a in value:
if a != b:
continue
else:
Dict2.append(a)
continue
But to no luck.

You can do something like this:
Dict = {'A':1, 'B':3, 'C':3, 'D':4, 'E':1}
result = {}
for k, v in Dict.items():
result.setdefault(v, set()).add(k)
print("Original: ")
print(Dict)
print("------------")
print("Result: ")
print(result)
Original:
{'A': 1, 'B': 3, 'C': 3, 'D': 4, 'E': 1}
Result:
{1: {'A', 'E'}, 3: {'B', 'C'}, 4: {'D'}}

Old school, with regular loops. Could maybe be done with list or dict comprehensions, but this is easy and obvious:
dict = {'A':1, 'B':3, 'C':3, 'D':4, 'E':1}
# Make a reverse dictionary that maps values to lists of keys
# that have that value in the original dict
reverse_dict = {}
for k, v in dict.items():
reverse_dict.setdefault(v, list()).append(k)
# Show the reverse dict
# print(reverse_dict)
# Move entries for keys that had duplicates from the original
# dict to a new dict
dups_dict = {}
for k, vs in reverse_dict.items():
if len(vs) > 1: # if there was more than one key with this value
for v in vs: # for each of those keys
dups_dict[v] = k # copy it to the new dict
del dict[v] # and remove it from the original dict
# Show the original dict and the new one
print(dict)
print(dups_dict)
Result:
{'D': 4}
{'A': 1, 'E': 1, 'B': 3, 'C': 3}

Related

Dictionary difference similar to set difference

I have a dictionary and a list:
dictionary = {'a':1, 'b':2, 'c':3, 'd':4, 'e':5, 'f':6}
remove = ['b', 'c', 'e']
I need to split "dictionary" into two dictionaries using "remove". The idea is to remove keys in "remove" from "dictionary" but instead of discarding them, I want to keep them in a new dictionary. The outcome I want is
old_dictionary = {'a':1, 'd':4, 'f':6}
new_dictionary = {'b':2, 'c':3, 'e':5}
Getting "new_dictionary" is fairly easy.
new_dictionary = {}
for key, value in dictionary.items():
if key in remove:
new_dictionary[key] = value
How do I find the difference between "dictionary" and "new_dictionary" to get "old_dictionary"? I guess I could loop again only with not in remove... but is there a nice trick for dictionaries similar to set difference?
One way could be to use dict.pop in loop. dict.pop method removes the key and returns its value. So in each iteration, we remove a key in remove from dictionary and add this key along with its value to new_dict. At the end of the iteration, dictionary will have all keys in remove removed from it.
new_dict = {k: dictionary.pop(k) for k in remove}
old_dict = dictionary.copy()
Output:
>>> new_dict
{'b': 2, 'c': 3, 'e': 5}
>>> old_dict
{'a': 1, 'd': 4, 'f': 6}
Just add else
new_dictionary = {}
old_dictionary = {}
for key, value in dictionary.items():
if key in remove:
new_dictionary[key] = value
else:
old_dictionary[key] = value
Use else: to put it in the other dictionary.
new_dictionary = {}
old_dictionary = {}
for key, value in dictionary.items():
if key in remove:
new_dictionary[key] = value
else:
old_dictionary[key] = value
The dict.keys() or dict.items() can be operated like a set with other iterable sequences:
>>> dictionary = {'a':1, 'b':2, 'c':3, 'd':4, 'e':5, 'f':6}
>>> remove = list('bce')
>>> new_dict = {key: dictionary[key] for key in remove}
>>> new_dict
{'b': 2, 'c': 3, 'e': 5}
>>> dict(dictionary.items() - new_dict.items())
{'d': 4, 'f': 6, 'a': 1}
However, in terms of performance, this method is not as good as the answer with the highest score.

How can I merge multiple dictionaries and add the values of the same key? (Python) [duplicate]

This question already has answers here:
Sum corresponding elements of multiple python dictionaries
(4 answers)
Closed 2 years ago.
Suppose I have the following dictionaries:
dict1 = {'a': 10, 'b': 8, 'c':3}
dict2 = {'c': 4}
dict3 = {'e':9, 'a':3}
I'm trying to merge them in a way such that the new (combinational) dictionary contains all the keys and all the values of the same key are added together. For instance, in this case, my desired output looks like:
dict = {'a': 13, 'b': 8, 'c':7, 'e':9}
It looks like the update() method doesn't work since some values are overwritten. I also tried ChainMaps and encountered the same issue. How can I merge multiple dictionaries and add the values of the same key?Thanks a lot:)
Here's a dictionary comprehension to achieve this using itertools.chain.from_iterable() and sum(). Here, I am creating a set of keys from all the three dicts. Then I am iteration over this set inside dictionary comprehension to get the sum of values per key.
>>> from itertools import chain
>>> dict1 = {'a': 10, 'b': 8, 'c':3}
>>> dict2 = {'c': 4}
>>> dict3 = {'e':9, 'a':3}
>>> my_dicts = dict1, dict2, dict3
>>> {k: sum(dd.get(k, 0) for dd in my_dicts) for k in set(chain.from_iterable(d.keys() for d in my_dicts))}
{'a': 13, 'e': 9, 'b': 8, 'c': 7}
This code below should do the trick:
dict1 = {'a': 10, 'b': 8, 'c':3}
dict2 = {'c': 4}
dict3 = {'e':9, 'a':3}
multiple_dict = [dict1, dict2, dict3]
final_dict = {}
for dict in multiple_dict:
for key, value in dict.items():
if key in final_dict:
final_dict[key] += value
else:
final_dict[key] = value
print(final_dict)

How to get dictionary keys and values if both keys are in two separated dictionaries?

I would like to get a new dictionary with keys only if both dictionaries have those keys in them, and then get the values of the second one.
# example:
Dict1 = {'A':3, 'B':5, 'C':2, 'D':5}
Dict2 = {'B':3, 'C':1, 'K':5}
# result--> {'B':3, 'C':1}
As a dictionary comprehension:
>>> {k:v for k, v in Dict2.items() if k in Dict1}
{'B': 3, 'C': 1}
Or use filter:
>>> dict(filter(lambda x: x[0] in Dict1, Dict2.items()))
{'B': 3, 'C': 1}
>>>
Just another solution, doesn't use comprehension. This function loops through the keys k in Dict1 and tries to add Dict2[k] to a new dict which is returned at the end. I think the try-except approach is "pythonic".
def shared_keys(a, b):
"""
returns dict of all KVs in b which are also in a
"""
shared = {}
for k in a.keys():
try:
shared[k] = b[k]
except:
pass
return shared
Dict1 = {'A':3, 'B':5, 'C':2, 'D':5}
Dict2 = {'B':3, 'C':1, 'K':5}
print(shared_keys(Dict1, Dict2))
# >>> {'B': 3, 'C': 1}

How d[key] is getting values of python dictionary in iteration(for loop) [duplicate]

This question already has answers here:
Iterating over dictionaries using 'for' loops
(15 answers)
Closed 4 years ago.
How d[key] is getting dictionary values in for loop? I know the other way to write dictionary code in for loop is:
d = {'a': 1, 'b': 2, 'c': 3}
for key, values in d.items():
print (key, 'corresponds to', values)
But I want to know how in below for loop how d[key] is getting values. Is there dictionary values are getting convert to list? Please help me here.
d = {'a': 1, 'b': 2, 'c': 3}
for key in d:
print (key, 'corresponds to', d[key])
When you simply iterate over a dict like that, you are actually iterating over the keys of the dictionary. For example:
>>> d = {'a': 1, 'b': 2, 'c': 3}
>>> list(d)
['a', 'b', 'c']
Then, d[key] accesses the value at the specified key in the dictionary.
It' because in the second snippet you are accessing directly the dict (d[key]):
d = {'a': 1, 'b': 2, 'c': 3}
for key in d:
print(key) # <-- see the output
print (key, 'corresponds to', d[key])
d.items() is a kind of helper which returns the pair key, value:
print(d.items()) #=> dict_items([('a', 1), ('b', 2), ('c', 3)])
Something like:
lst = [(1,2), (2,4)]
for k,v in lst:
print(k, v)

Reverting a dictionary in Python [duplicate]

This question already has answers here:
switching keys and values in a dictionary in python [duplicate]
(10 answers)
Closed 5 years ago.
I'm sorry if this is a foolish question or a duplicate - I looked but didn't really find anything on this specific question:
I wrote a little cyphering tool for practise, now I'm working on the deciphering part and wondering, how I can use the dictionary I used as a lookuptable to revert this... I can't access the dictionary's key via its value, right?
So I thought I'd turn it around like this:
for x, y in cyphertable.items():
DEcyphertable = dict(zip(x, y))
But this doesn't seem to work.
A: What am I doing wrong?
and B: How else could I make each "i" in a string look up the value and replace it with the corresponding key?
Using Dict comprehension
reverted_dict = {value: key for key, value in cyphertable.items()}
Using zip
reverted_dict = dict(zip(cyphertable.values(), cyphertable.keys()))
You can do that simply by:
new_dict = {v: k for k, v in old_dict.items()}
But, note that you may loose some items if you have duplicated values in old_dict (values become keys and keys are unique in a dict).
Outputs:
>>> old_dict = {'a': 1, 'b': 2}
>>> new_dict = {v: k for k, v in old_dict.items()}
>>> new_dict
{1: 'a', 2: 'b'}
If old_dict contains duplicated values:
>>> old_dict = {'a': 1, 'b': 2, 'c': 1}
>>> new_dict = {v: k for k, v in old_dict.items()}
>>> new_dict
{1: 'c', 2: 'b'}
Here it is,
In [38]: a = {'a':1,'b':2,'c':3}
In [39]: {j:i for i,j in a.items()}
Out[39]: {1: 'a', 2: 'b', 3: 'c'}
Or
In [40]: dict(zip(a.values(),a.keys()))
Out[40]: {1: 'a', 2: 'b', 3: 'c'}

Categories

Resources