Reverse searches by values in many dictionaries

Question:

A pile of small dictionaries like these:

born_place = {"David":"New York", "Juan":"Dallas"}
childhood_place = {"David":"Los Angeles"}
school_place = {"Mike":"New York", "David":"Houston"}
work_place = {"Kate":"Phoenix"}
university_place = {"Mike":"Chicago"}

I want to check, in a list of cities, all the names related (regardless what ‘xx_place" is):

New York, Los Angeles, Chicago, Houston, Phoenix, Dallas

By doing the lines as below, I am able to check the "born_place" of 1 city:

New_York = []
Chicago = []
Houston = []
Phoenix = []
Dallas = []

try:
    ny = list(born_place.keys())[list(born_place.values()).index('New York')] # reverse search in a dictionary
    New_York.append(ny)
except:
    pass

print (New_York)

The block of code is only for 1 xx_place for 1 city. 6 cities with 5 places require 30 blocks of these codes. (if the list of cities and and xx_place are longer…)

Asked By: Mark K

||

Answers:

IIUC, you can use defaultdict(list) and insert name of dict to key of city.

if the list of cities and xx_place are longer. if all city_name exist in dicts and you don’t want to check. You don’t need to create a list of cities and You can create a list of dict for xx_place.

from collections import defaultdict
res = defaultdict(list)

# You can create a list of dict
# places = [{"David":"New York", "Juan":"Dallas"}, 
#           {"David":"Los Angeles"}, 
#           {"Mike":"New York", "David":"Houston"}, 
#           {"Kate":"Phoenix"}, {"Mike":"Chicago"}]

# if you want to use 'list' of 'dict'
# for place in places:

for place in [born_place, childhood_place, school_place, 
              work_place, university_place]:
    for k,v in place.items():
        res[v].append(k)
                
print(res)

{
    'New York': ['David', 'Mike'], 
    'Los Angeles': ['David'], 
    'Chicago': ['Mike'], 
    'Houston': ['David'], 
    'Phoenix': ['Kate'], 
    'Dallas': ['Juan']
}
Answered By: I'mahdi

The dictionaries can be combined together and traversed

from collections import defaultdict


born_place = {"David":"New York", "Juan":"Dallas"}
childhood_place = {"David":"Los Angeles"}
school_place = {"Mike":"New York", "David":"Houston"}
work_place = {"Kate":"Phoenix"}
university_place = {"Mike":"Chicago"}
res = defaultdict(list)
for item in [born_place, childhood_place, school_place, work_place, university_place]:
    for k, v in item.items():
        res[v].append(k)
print(dict(res))

# {'New York': ['David', 'Mike'], 'Dallas': ['Juan'], 'Los Angeles': ['David'], 'Houston': ['David'], 'Phoenix': ['Kate'], 'Chicago': ['Mike']}
Answered By: maya

Without using defaultdict you can utilise setdefault as follows:

born_place = {"David":"New York", "Juan":"Dallas"}
childhood_place = {"David":"Los Angeles"}
school_place = {"Mike":"New York", "David":"Houston"}
work_place = {"Kate":"Phoenix"}
university_place = {"Mike":"Chicago"}

result = {}
for d in born_place, childhood_place, school_place, work_place, university_place:
    for k, v in d.items():
        result.setdefault(v, []).append(k)

print(result)

Output:

{'New York': ['David', 'Mike'], 'Dallas': ['Juan'], 'Los Angeles': ['David'], 'Houston': ['David'], 'Phoenix': ['Kate'], 'Chicago': ['Mike']}
Answered By: Stuart

With if statement instead of defaultdict:

born_place = {"David":"New York", "Juan":"Dallas"}
childhood_place = {"David":"Los Angeles"}
school_place = {"Mike":"New York", "David":"Houston"}
work_place = {"Kate":"Phoenix"}
university_place = {"Mike":"Chicago"}

places = [born_place, childhood_place, school_place, work_place, university_place]
results = {}

for d in places:
    for k, v in d.items():
        if v not in results.keys():
            results[v] = []
        results[v].append(k)
        
print(results['New York'])
Answered By: math_noob
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.