Reputation: 43
I have a bunch of lists that contain elements that are related to each other and I want to convert them to a single dictionary with lists as values:
list1 = ['cat', 'animal']
list2 = ['dog', 'animal']
list3 = ['crow', 'bird']
result = {'animal': ['cat', 'dog'], 'bird': 'crow'}
How could I do that?
Upvotes: 3
Views: 715
Reputation: 30453
Simple approach:
data = [['cat', 'animal'], ['dog', 'animal'], ['crow', 'bird']]
result = {}
for value, key in data:
result[key] = result.get(key, []) + [value]
result #=> {'bird': ['crow'], 'animal': ['cat', 'dog']}
Using defaultdict
:
from collections import defaultdict
data = [['cat', 'animal'], ['dog', 'animal'], ['crow', 'bird']]
result = defaultdict(list)
for value, key in data:
result[key].append(value)
result #=> defaultdict(<class 'list'>, {'animal': ['cat', 'dog'], 'bird': ['crow']})
Using groupby
from itertools
:
from itertools import groupby
data = [['cat', 'animal'], ['dog', 'animal'], ['crow', 'bird']]
{k: [x[0] for x in g] for k, g in groupby(data, lambda x: x[1])}
#=> {'bird': ['crow'], 'animal': ['cat', 'dog']}
Using reduce
from functools
:
from functools import reduce
data = [['cat', 'animal'], ['dog', 'animal'], ['crow', 'bird']]
reduce(lambda a, e: dict(a, **{e[1]: a.get(e[1], []) + [e[0]]}), data, {})
#=> {'bird': ['crow'], 'animal': ['cat', 'dog']}
Upvotes: 5
Reputation: 71451
You can merely iterate over a nested list of original data and use a OrderedDict
to retain the order of entry:
from collections import OrderedDict
data = [
['cat', 'animal'],
['dog', 'animal'],
['crow', 'bird']
]
d = OrderedDict()
for name, type in data:
if type in d:
d[type].append(name)
else:
d[type] = [name]
Output:
OrderedDict([('animal', ['cat', 'dog']), ('bird', ['crow'])])
Upvotes: 1
Reputation: 109528
Given that your lists consists of pairs where the first item is the value and the second is the key, you can use a defaultdict constructed with lists and then just append the results.
from collections import defaultdict
dd = defaultdict(list)
my_lists = [list1, list2, list3]
for my_paired_list in my_lists:
v, k = my_paired_list
dd[k].append(v)
>>> dict(dd)
{'animal': ['cat', 'dog'], 'bird': ['crow']}
If you don't want keys with only one element to be in a list (e.g. 'bird': ['crow']
should be 'bird': 'crow'
), then just convert the result:
new_result = {k: v[0] if len(v) == 1 else v for k, v in dd.iteritems()}
>>> new_result
{'animal': ['cat', 'dog'], 'bird': 'crow'}
Upvotes: 1
Reputation: 40878
The other answers using defaultdict
don't exactly match your intended output. Here's a version without defaultdict
that does.
list1=['cat','animal']
list2=['dog','animal']
list3=['crow','bird']
dict1 = {}
for v, k in (list1, list2, list3):
if k in dict1:
# If the value already exists (as string), convert it to list
# and append the new value
dict1[k] = [dict1[k]]
dict1[k].append(v)
else:
# Otherwise, we just want a string, not list
dict1[k] = v
print(dict1)
{'animal': ['cat', 'dog'], 'bird': 'crow'}
Upvotes: 1
Reputation: 1180
If you have tuple of lists or list of lists following coed will be suitable. If you have defined variables with lists, you can simply add all lists into one variable firstly and then process it with algorithm written below.
lists = ['cat','animal'],['dog','animal'],['crow','bird']
results = {}
for list in lists:
if list[1] in results:
results[list[1]].append(list[0])
print('bingo')
else:
results[list[1]] = [list[0]]
print(results)
Upvotes: 1
Reputation: 36598
You can use the defaultdict
from the collections
module. It is part of the standard library and operates the same as a dictionary with the exception that if a new key is passed, it will create a new value (a list in this case) automatically
list1=['cat','animal']
list2=['dog','animal']
list3=['crow','bird']
from collections import defaultdict
# create a new dictionary where an unknown key will automatically
# add the key to the dictionary with a empty list as the value
d = defaultdict(list)
# iterate over your lists, updating the dictionary
for value, key in (list1, list2, list3):
d[key].append(value)
d
# returns:
defaultdict(list, {'animal': ['cat', 'dog'], 'bird': ['crow']})
Upvotes: 1
Reputation: 713
If you have a list of lists that you want to convert, you can do this:
dict1 = {}
for li in lists:
if(li[1] not in dict1):
dict1[li[1]] = []
dict1[li1].append(li[0])
Note that this will produce dict1={'animal':['cat','dog'],'bird':['crow']}
instead of dict1={'animal':['cat','dog'],'bird':'crow'}
, which is what you have in the question.
Upvotes: 1