Flat map list without losing mapping? - python

I have a existing dict that maps single values to lists.
I want to reverse this dictionary and map from every list entry on the original key.
The list entries are unique.
Given:
dict { 1: ['a', 'b'], 2: ['c'] }
Result:
dict { 'a' : 1, 'b' : 1, 'c' : 2 }
How can this be done?

Here's an option
new_dict = {v: k for k, l in d.items() for v in l}
{'a': 1, 'b': 1, 'c': 2}

You can use a list comprehension to produce a tuple with the key-value pair, then, flatten the new list and pass to the built-in dictionary function:
d = { 1: ['a', 'b'], 2: ['c'] }
new_d = dict([c for h in [[(i, a) for i in b] for a, b in d.items()] for c in h])
Output:
{'a': 1, 'c': 2, 'b': 1}

Related

Python Index Nested Dictionary with List

If I have a nested dictionary and varying lists:
d = {'a': {'b': {'c': {'d': 0}}}}
list1 = ['a', 'b']
list2 = ['a', 'b', 'c']
list3 = ['a', 'b', 'c', 'd']
How can I access dictionary values like so:
>>> d[list1]
{'c': {'d': 0}}
>>> d[list3]
0
you can use functools reduce. info here. You have a nice post on reduce in real python
from functools import reduce
reduce(dict.get, list3, d)
>>> 0
EDIT: mix of list and dictioanries
in case of having mixed list and dictionary values the following is possible
d = {'a': [{'b0': {'c': 1}}, {'b1': {'c': 1}}]}
list1 = ['a', 1, 'b1', 'c']
fun = lambda element, indexer: element[indexer]
reduce(fun, list1, d)
>>> 1
Use a short function:
def nested_get(d, lst):
out = d
for x in lst:
out = out[x]
return out
nested_get(d, list1)
# {'c': {'d': 0}}

find particular value from list of dict in python

I have a list of dictionaries like this:
s = [{'a':1,'b':2},{'a':3},{'a':2},{'a':1}]
remove duplicate value pair
and I want a list of dictionaries like:
s = [{'a':1},{'a':3},{'a':2}]
Use list comprehension with filter a:
s = [{k: v for k, v in x.items() if k =='a'} for x in s]
print (s)
[{'a': 1}, {'a': 3}, {'a': 2}]
You could use a list comprehension adding new dictionary entries only if 'a' is contained:
[{'a':d['a']} for d in s if 'a' in d]
# [{'a': 1}, {'a': 3}, {'a': 2}]
You can try this.
s = [{'a':1,'b':2},{'a':3},{'a':2}]
s=[{'a':d['a']} for d in s]
# [{'a': 1}, {'a': 3}, {'a': 2}]
If you want to have a list of singleton dictionaries with only a keys, you can do this:
>>> [{'a': d.get('a')} for d in s]
[{'a': 1}, {'a': 3}, {'a': 2}]
But this just seems more suitable for a list of tuples:
>>> [('a', d.get('a')) for d in s]
[('a', 1), ('a', 3), ('a', 2)]
From the docs for dict.get:
Return the value for key if key is in the dictionary, else default. If default is not given, it defaults to None, so that this method never raises a Key Error.

How to make all the dictionary values unique in python?

I want a solution to make all the keys of a dictionary have a unique value, and to do that delete the values as minimum as possible to have each value unique. For example:
my_dict = {'c': 3, 'e': 3, 'a': 2, 'f': 2, 'd': 2}
for the above dictionary I need to sub 2 from 'f' and 3 of times from 'e' and 1 time from 'd'. and result would be 6 which means {'c':3, 'a':2, 'd':1}. Removing keys is not a problem.
note we could remove 'c' rather than 'e' or 'a' rather than f'' it's not important which key should be decreed or be removed , what matters is having unique values
This is what I have tried:
for k, v in my_dict.items():
c = 0
while len(my_dict.values()) > len(set(my_dict.values())):
my_dict[k] = my_dict[k] -1
c += 1
It is not the result you were expecting, but it meets the requirements.
my_dict = {'c': 3, 'e': 3, 'a': 2, 'f': 2, 'd': 2}
to_remove = []
result = {}
for key, value in my_dict.items():
while value > 0:
if value not in to_remove:
to_remove.append(value)
result[key] = value
break
else:
value -= 1
result
Simple approach:
my_dict = {'c': 3, 'e': 3, 'a': 2, 'f': 2, 'd': 2}
rd = {v: k for k, v in my_dict.items()}
my_dict = {v: k for k, v in rd.items()}
print(my_dict)

How can i add the terms of one dict to another?

Let's assume i start with this dictionary:
mydict = {
'a': [[2,4], [5,6]],
'b': [[1,1], [1,7,9], [6,2,3]],
'c': [['a'], [4,5]],
}
How can i append values to 'a' yet be able to add a new key if i needed to let's say 'd' what i tried is
plus_min_dict = {}
plus_min_dict[key] = reference_dataset[key][line_number]
but it only gave one value per key apparently = destroyed the previous value, i want to update or append yet still be able to create a new key if it doesn't exist
Edit: To clarify let's assume this is my initial dictionary:
mydict = {
'a': [[2,4]],}
i do other calculations with another dictionary let's assume it's :
second_dict = {
'a': [ [5,6]],
'b': [[1,1], [1,7,9]],
'c': [['a'], [4,5]],
}
these calculations showed me that i have interest in [5,6] of 'a' and [1,7,9] of 'b' so i want mydict to become:
mydict = {
'a': [[2,4], [5,6]],
'b': [[1,7,9]],
}
If I understand well your question, you want to append a new value to your dictionary if the key already exists. If so, I would use a defaultdict for a simple reason. With a defaultdict you can use the method += to create (if does not exist) or add (if exist) an element :
from collections import defaultdict
# Your dictionaries
mydict = {
'a': [[2,4], [5,6]],
'b': [[1,1], [1,7,9], [6,2,3]],
'c': [['a'], [4,5]],
}
plus_min_dict = {'a': [[3,3]]}
# d is a DefaultDict containing mydict values
d=defaultdict(list,mydict)
# d_new is a DefaultDict containing plus_min_dict dict
d_new = defaultdict(list, plus_min_dict)
# Add all key,values of d in d_new
for k, v in d.items():
d_new[k] += d[k]
print(d_new)
Results :
defaultdict(<class 'list'>, {'c': [['a'], [4, 5]], 'a': [[3, 3], [2, 4], [5, 6]], 'b': [[1, 1], [1, 7, 9], [6, 2, 3]]})
Use an if else loop
mydict = {'a': [[2,4]],}
second_dict = {
'a': [ [5,6]],
'b': [[1,1], [1,7,9]],
'c': [['a'], [4,5]]}
missing_values = {
'a': [5,6],
'b': [1,7,9]}
for key, value in missing_values.items():
if key in mydict:
mydict[key ].append(value)
else:
mydict[key ] = [value]
print(mydict)
Result:
{'a': [[2, 4], [5, 6]], 'b': [[1, 7, 9]]}
To append an item into 'a', you can do this:
mydict['a'] += ['test_item']
Or:
mydict['a'].append('test_item')
You can just append:
mydict = {
'a': [[2,4], [5,6]],
'b': [[1,1], [1,7,9], [6,2,3]],
'c': [['a'], [4,5]],
}
mydict['a'].append([7,8])
mydict['d'] = [0,1]
print(mydict)

How to "sort" a dictionary by number of occurrences of a key?

I have a dictionary of values that gives the number of occurrences of a value in a list. How can I return a new dictionary that divides the former dictionary into separate dictionaries based on the value?
In other words, I want to sort this dictionary:
>>> a = {'A':2, 'B':3, 'C':4, 'D':2, 'E':3}
to this one.
b = {2: {'A', 'D'}, 3: {'B', 'E'}, 4: {'C'}}
How do I approach the problem?
from collections import defaultdict
a = {'A': 2, 'B': 3, 'C': 4, 'D': 2, 'E': 3}
b = defaultdict(set)
for k, v in a.items():
b[v].add(k)
This is what you'll get:
defaultdict(<class 'set'>, {2: {'D', 'A'}, 3: {'B', 'E'}, 4: {'C'}})
You can convert b to a normal dict afterwards with b = dict(b).
if you are a python beginner like me, you probably wanna try this
a = {'A': 2 , 'B': 3 , 'C' : 4 , 'D' : 2, 'E' : 3}
b = {}
for key in a:
lst = []
new_key = a[key]
if new_key not in b:
lst.append(key)
b[new_key] = lst
else:
b[new_key].append(key)
print(b)
It uses the mutable property of python dictionary to achieve the result you want.

Categories