I have the following dictionary.
dict = {}
dict['key1'] = ['A', 'B', 'C']
dict['key2'] = ['B', 'D']
dict['key3'] = ['A', 'C', 'E']
I'd like to create a new dictionary that holds all combinations of letters to other letters in the same list.
I'd like the final result to look like this.
{
'A': ['B', 'C', 'E'],
'B': ['A', 'C', 'D'],
'C': ['A', 'B', 'E'],
'D': ['B'],
'E': ['A', 'C']
}
I tried to initialize a new dictionary of empty lists and iterate through each list to get the combination and append to the dictionary of lists, but I seem to be missing something.
dict = {}
dict['key1'] = ['A', 'B', 'C']
dict['key2'] = ['B', 'D']
dict['key3'] = ['A', 'C', 'E']
dict2={}
list = ['A', 'B', 'C', 'D', 'E']
# instantiate dict2
for i in list:
dict2[i]=[]
for idx, key in enumerate(dict):
print(key, dict[key])
tmp = dict[key]
for x in tmp:
tmp.remove(x)
for y in tmp:
dict2[x].append(y)
I'd suggest using a dict of sets as an intermediate step and then converting to lists for the final result:
# Initial data. (Don't use 'dict' as a variable name!)
my_dict = {
'key1': ['A', 'B', 'C'],
'key2': ['B', 'D'],
'key3': ['A', 'C', 'E'],
}
# Build all combinations as a dict of sets.
all_combos = {}
for v in my_dict.values():
for x in v:
all_combos.setdefault(x, set()).update(v)
all_combos[x].remove(x)
# Convert dict of sets to dict of sorted lists.
final_dict = {k: sorted(v) for k, v in all_combos.items()}
from pprint import pprint
pprint(final_dict)
prints:
{'A': ['B', 'C', 'E'],
'B': ['A', 'C', 'D'],
'C': ['A', 'B', 'E'],
'D': ['B'],
'E': ['A', 'C']}
Just to complement Samwise's way by a set comprehension method:
dict = {}
dict['key1'] = ['A', 'B', 'C']
dict['key2'] = ['B', 'D']
dict['key3'] = ['A', 'C', 'E']
dict2 = {key: val for key, val in zip(set([item for sublist in dict.values() for item in sublist]), [set([item for sublist in [x for x in dict.values() if key in x] for item in sublist]) for key in set([item for sublist in dict.values() for item in sublist])])}
Last step would only be to remove the key from each set, but I am sure you'd be able to do this:)
Using a collections.defaultdict
we can first create a dictionary listing all characters that occur with each character.
Then we can use a dictionary comprehension to convert those lists to a set and remove the actual key character.
from collections import defaultdict
d = defaultdict(list)
for k, v in my_dict.items():
s = set(v)
for c in s:
d[c] += list(s)
# d = defaultdict(<class 'list'>, {'A': ['A', 'C', 'B', 'A', 'C', 'E'], 'C': ['A', 'C', 'B', 'A', 'C', 'E'], 'B': ['A', 'C', 'B', 'D', 'B'], 'D': ['D', 'B'], 'E': ['A', 'C', 'E']})
e = {k: set(v) ^ set([k]) for k, v in d.items()}
# e = {'A': {'C', 'B', 'E'}, 'C': {'A', 'B', 'E'}, 'B': {'C', 'A', 'D'}, 'D': {'B'}, 'E': {'A', 'C'}}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.