Printing unique keys from nested dictionary in python - python

I have a dictionary dict_matches with 2 inner dictionaries.
The structure of dict_match is as follows:
dict_match = {Query_ID:{Function_ID:{DB_ID:[func_ID]}}}
Within the top level of keys Query_ID, I loop through these and compare these against keys in a completely separate dict query_count_dict to determine the overlap of keys.
Within this loop I also navigate to the base dict in dict_matches in order to see what keys DB_ID the master key has 'matched' with. My problem is that this lower-level of keys DB_ID that correspond to the very top-level key Query_ID can be duplicated (and I only want to see the unique keys). I tried using the set() method but this actually split the string keys into their character components and printed the unique characters for each lower-level key. Any help appreciated!
See code below
for k,v in dict_match.items():
if k in query_count_dict.keys():
print(k)
detection_query.append(k)
print(len(dict_match[k])/int(query_count_dict[k]))
if type(v) is dict:
recursive_items(v)
where recursive_items is a function to navigate to the base dict:
def recursive_items(dictionary):
for k, v in dictionary.items():
if type(v) is dict:
recursive_items(v)
else:
print(set(k))

You can print all the unique keys by passing a list of keys in your recursive function, to store them as you navigate to the base. Then cast it to set to remove the duplicates.
def get_keys(dictionary, keys=[]):
for k, v in dictionary.items():
keys.append(k)
if isinstance(v, dict):
get_keys(v, keys)
return set(keys)
dict_match = {'A': {'A': {'B': [0], 'H': [0]}, 'D': {'C': [0], 'A': [0]}},
'B': {'C': {'A': [0]}, 'G': {'A': [0]}},
'C': {'A': {'E': [0]}, 'B': {'F': [0], 'A': [0]}, 'C': {'B': [0]}}}
print(get_keys(dict_match))
And it will output only the unique keys:
{'G', 'B', 'E', 'F', 'C', 'H', 'A', 'D'}

Related

How to change the positions of a dictionary? [duplicate]

This question already has answers here:
Reverse / invert a dictionary mapping
(32 answers)
Closed 10 months ago.
I have a dictionary as follows:
d = {'a': ['b'], 'c': ['d']}
I want to change the positions of the dictionary so that it looks like the following:
d_new = {'b': 'a', 'd': 'c'}
I have tried the following, but due to the second term being a list in my original dictionary (d), I am unable to complete this.
d = {'a': ['b'], 'c': ['d']}
for k in list(d.keys()):
d[d.pop(k)] = k
print(d)
You can use iterable unpacking in a dict comprehension like so:
{v: k for k, (v,) in d.items()}
>>> d = {'a': ['b'], 'c': ['d']}
>>> {v: k for k, (v,) in d.items()}
{'b': 'a', 'd': 'c'}
This assumes all values are a list of one element and you only want the first element in the lists.
Otherwise you can use this more appropriate code:
{v[0] if isinstance(v, list) else v: k for k, v in d.items()}
A variation on a theme using list unpacking:
d = {'a': ['b'], 'c': ['d']}
d = {v: k for k, [v] in d.items()}
print(d)
In case the values (lists) happen to contain more than one element and you're only interested in the first element then:
d = {v:k for k, [v,*_] in d.items()}
Of course, this could also be used even if there's only one element per list

How to merge keys of dictionary which have the same value?

I need to combine two dictionaries by their value, resulting in a new key which is the list of keys with the shared value. All I can find online is how to add two values with the same key or how to simply combine two dictionaries, so perhaps I am just searching in the wrong places.
To give an idea:
dic1 = {'A': 'B', 'C': 'D'}
dic2 = {'D': 'B', 'E': 'F'}
Should result in:
dic3 = {['A', 'D']: 'B', 'C': 'D', 'E': 'F'}
I am not sure why you would need such a data structure, you can probably find a better solution to your problem. However, just for the sake of answering your question, here is a possible solution:
dic1 = {'A':'B', 'C':'D'}
dic2 = {'D':'B', 'E':'F'}
key_list = list(dic2.keys())
val_list = list(dic2.values())
r = {}
for k,v in dic1.items():
if v in val_list:
i = val_list.index(v) #get index at value
k2 = key_list[i] #use index to retrive the key at value
r[(k, k2)] = v #make the dict entry
else:
r[k] = v
val_list = list(r.values()) #get all the values already processed
for k,v in dic2.items():
if v not in val_list: #if missing value
r[k] = v #add new entry
print(r)
output:
{('A', 'D'): 'B', 'C': 'D', 'E': 'F'}
You can't assign a list as a key in a python dictionary since the key must be hashable and a list is not an ashable object, so I have used a tuple instead.
I would use a defaultdict of lists and build a reversed dict and in the end reverse it while converting the lists to tuples (because lists are not hashable and can't be used as dict keys):
from collections import defaultdict
dic1 = {'A':'B', 'C':'D'}
dic2 = {'D':'B', 'E':'F'}
temp = defaultdict(list)
for d in (dic1, dic2):
for key, value in d.items():
temp[value].append(key)
print(temp)
res = {}
for key, value in temp.items():
if len(value) == 1:
res[value[0]] = key
else:
res[tuple(value)] = key
print(res)
The printout from this (showing the middle step of temp) is:
defaultdict(<class 'list'>, {'B': ['A', 'D'], 'D': ['C'], 'F': ['E']})
{('A', 'D'): 'B', 'C': 'D', 'E': 'F'}
If you are willing to compromise from 1-element tuples as keys, the second part will become much simpler:
res = {tuple(value): key for key, value in temp.items()}

How to find keys whose values are the same (values are also dictionaries)

There is a graph (please see the example here) and I am using a dictionary to store the adjacency matrix:
{A:{B:a, C:a, D:a}, B:{A:a, E:b}, C:{A:a}, D:{A:a}, E:{B:b}}
where uppercase letters are nodes, lowercase letters are edges.
I am trying to find nodes who have the same adjacency (C, D in this example). How can I implement it? Changing the data structure of the adjacency matrix is fine. Any help would be appreciated.
You can iterate the graph and for each two distinct nodes check if adjacency details of those are the same, by using == operator.
graph = {
'A': {'B': 'a', 'C': 'a', 'D': 'a'},
'B': {'A': 'a', 'E': 'b'},
'C': {'A': 'a'},
'D': {'A': 'a'},
'E': {'B': 'b'},
}
res = {}
for u, u_adj in graph.items():
res.setdefault(u, [])
for v, v_adj in graph.items():
if u != v and u_adj == v_adj:
res[u].append(v)
print(res)
if I understand correctly your Problem then this can be a Solution for you if your data type is a Dictionary:
temp = {}
for key, value in your_dictionary.items():
temp.setdefault(value, set()).add(key)
if you then want to retrieve the keys who have the same values from a Dictionary then you can use this:
res = [values for key, values in temp.items() if len(values) > 1]

How to target a specific key in a dictionary?

I am making a simple program and need help.
memory = {'a': 'a', 'b': 'b'}
for key, value in memory.items():
print(key)
I need to target a specific key like this: x = '2', memory = {'a': '1', 'b': '2'}, for k, v in memory.items(x):, print(k). My idea is that the x should decide which key should be printed by it's value.
I'm not entirely sure what your asking for, but do you want to print the value?
memory = {'a': 'A', 'b': 'B'}
for key, value in memory.items():
print('key = {}'.format(key))
print('value = {}'.format(value))
or only the b value?
print(memory['b'])
or do you want to print the key for which the value is B?
for key, val in memory.items():
if val == 'B':
print('key = {}'.format(key))
Use keys() method to get list keys and then iterate over them in the for loop
memory = {'a': 'a', 'b': 'b'}
for key in memory.keys():
print(key)
# if you need the corresponding value
print(memory[key])

specific value based filtering on a large dictionary in Python

I am having a very large dictionary. Here is a small sampling of my dictionary:
dictionary = {'1': {'a':'aa','b':'bb','c':'cc','d':'dd'},
'2': {'a':'aa','b':'bb','c':'cc','d':'dd'},
'3': {'a':'aa','b':'bb','c':'cc','d':'dd'} }
I just want to filter out the a & c.
Desired output:
dictionary = { '1': {'a':'aa','c':'cc'},
'2': {'a':'aa','c':'cc'},
'3': {'a':'aa','c':'cc'} }
Dictionary comprehensions to the rescue:
{k: {'a': v['a'], 'c': v['c']} for k, v in dictionary.iteritems()}
This assumes that all dictionaries in have those keys set and that you are using Python 2.7.
A more generic version:
def filtered_dicts(d, keys):
return {k: {vk: v[vk] for vk in v.viewkeys() & keys} for k, v in d.iteritems()}
dictionary = filtered_dicts(dictionary, {'a', 'c'})
This will work even if the keys are not present in all values of dictionary.
Any iterable will do for keys here; I used a set literal here but a list or tuple or even a string would work too.
A Python 3 version of the latter:
def filtered_dicts(d, keys):
return {k: {vk: v[vk] for vk in v.keys() & keys} for k, v in d.items()}
Quick demo using Python 3:
>>> dictionary = {'1': {'a':'aa','b':'bb','c':'cc','d':'dd'}, '2': {'a':'aa','b':'bb','c':'cc','d':'dd'}, '3':{'a':'aa','b':'bb','c':'cc','d':'dd'}}
>>> def filtered_dicts(d, keys):
... return {k: {vk: v[vk] for vk in v.keys() & keys} for k, v in d.items()}
...
>>> filtered_dicts(dictionary, {'a', 'c'})
{'3': {'c': 'cc', 'a': 'aa'}, '2': {'c': 'cc', 'a': 'aa'}, '1': {'c': 'cc', 'a': 'aa'}}

Categories

Resources