简体   繁体   中英

Create new dictionary of value combinations from another dictionary

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM