Inverting a dictionary with list values
I've tried around and you want to use val not in inverse
but it can't be checked if a "list is in a dict". (val
is a list)
For your code a simple change will do what you want:
def invert_dict(d):
inverse = dict()
for key in d:
# Go through the list that is saved in the dict:
for item in d[key]:
# Check if in the inverted dict the key exists
if item not in inverse:
# If not create a new list
inverse[item] = [key]
else:
inverse[item].append(key)
return inverse
pythonic way to reverse a dict where values are lists?
This is well-suited for collections.defaultdict
:
>>> from collections import defaultdict
>>> numbers_by_letter = defaultdict(list)
>>> for k, seq in letters_by_number.items():
... for letter in seq:
... numbers_by_letter[letter].append(k)
...
>>> dict(numbers_by_letter)
{'a': [1, 3, 4], 'b': [1, 2, 5], 'c': [1, 3, 5], 'd': [1, 2, 4]}
Note that you don't really need the final dict()
call (a defaultdict
will already give you the behavior you probably want), but I included it here because the result from your question is type dict
.
Inverting a dictionary with sets/lists as values
dict.fromkeys(d, set())
just creates one set
and puts that in every dictionary entry. You need to create a new set for each entry:
inverse_dict = {k: set() for k in d}
Reverse / invert a dictionary mapping
Python 3+:
inv_map = {v: k for k, v in my_map.items()}
Python 2:
inv_map = {v: k for k, v in my_map.iteritems()}
How to reverse a dictionary (whose values are lists) in Python?
You can do it very simply like this:
newdict = {}
for key, value in olddict.items():
for string in value:
newdict.setdefault(string, []).append(key)
How can I flatten a dictionary with a list for values?
Use a dictionary comprehension with nested iteration:
>>> d = {
... "USA": ["US", "United States"],
... "SGP": ["JP", "Japan", "Singapore"]
... }
>>> {i: k for k, v in d.items() for i in v}
{'US': 'USA', 'United States': 'USA', 'JP': 'SGP', 'Japan': 'SGP', 'Singapore': 'SGP'}
k, v in d.items()
->k = "USA", ...
,v = ["US", "United States"], ...
i in v
->i = "US", ...
hence:
{i: k ...}
->{"US": "USA", ...}
Python 3: How Do I Invert A Dictionary That Has A List As A Value
You can use a defaultdict to remove the else statement and to check if the key exists. If it doesn't exists an empty list will be created.
from pprint import pprint
summon_locations = {
"Solaire": ['Gargoyles', 'Gaping Dragon', "Ornstein/Smough"],
"Gotthard": ['Abyss Watchers', 'Pontiff Sulyvahn', "Grand Archives"],
"Lucatiel": ['Lost Sinner', 'Smelter Demon', 'Abyss Watchers'],
}
if __name__ == '__main__':
from collections import defaultdict
inverted = defaultdict(list)
for key, values in summon_locations.items():
for value in values:
inverted[value].append(key)
pprint(inverted)
Output
defaultdict(<class 'list'>,
{'Abyss Watchers': ['Gotthard', 'Lucatiel'],
'Gaping Dragon': ['Solaire'],
'Gargoyles': ['Solaire'],
'Grand Archives': ['Gotthard'],
'Lost Sinner': ['Lucatiel'],
'Ornstein/Smough': ['Solaire'],
'Pontiff Sulyvahn': ['Gotthard'],
'Smelter Demon': ['Lucatiel']})
Which is similar to the the one-liner
[inverted[value].append(key) for key, values in summon_locations.items() for value in values]
But one liners are not always better, in this case I would stay with the two for loops.
Invert a dictionary with list values in ansible
The playbook
- hosts: localhost
vars:
dict1:
host1: [tag1, tag2]
host2: [tag1]
tasks:
- set_fact:
dict2: "{{ dict2|default({})|combine({item: list_of_hosts}) }}"
loop: "{{ dict1.values()|flatten|unique }}"
vars:
list_of_hosts: "{{ dict1|
dict2items|
selectattr('value', 'contains', item)|
map(attribute='key')|
list }}"
- debug:
var: dict2
gives
dict2:
tag1: [host1, host2]
tag2: [host1]
Optionally, use json_query
vars:
list_of_hosts: "{{ dict1|dict2items|json_query(_query) }}"
_query: '[?value.contains(@, `{{ item }}`)].key'
Related Topics
Logger Configuration to Log to File and Print to Stdout
Does Python Have a Module to Convert CSS Styles to Inline Styles for Emails
Matplotlib Analog of R's 'Pairs'
Different Yaml Array Representations
How to Print Variable and String on Same Line in Python
How to Return a Value from _Init_ in Python
What's the Best Way to Return Multiple Values from a Function
How to Send an Email with Python
How to Use Mingw's Gcc Compiler When Installing Python Package Using Pip
Pyqt Showing Video Stream from Opencv
Styling Multi-Line Conditions in 'If' Statements
Control the Size Textarea Widget Look in Django Admin
How to Implement R's P.Adjust in Python
How to Decrypt Aws Ruby Client-Side Encryption in Python