Reputation: 307
I am trying to create a dictionary from a list of lists. I create an example to something similar I am working on, which goes like this:
lst1 = [['a','b','c'],['d','e','a'],['g','b','i']]
lst2 = [[1,8,2],[4,3,6],[7,9,0]]
I tried something like this
mydict = [dict(zip(keys,values)) for keys in lst1 for values in lst2]
print (mydict)
# Prints like this below
#[{'a': 1, 'b': 8, 'c': 2}, {'a': 4, 'b': 3, 'c': 6}, {'a': 7, 'b': 9, 'c': 0}, {'d': 1, 'e': 8, 'a': 2}, {'d': 4, 'e': 3, 'a': 6}, {'d': 7, 'e': 9, 'a': 0}, {'g': 1, 'b': 8, 'i': 2}, {'g': 4, 'b': 3, 'i': 6}, {'g': 7, 'b': 9, 'i': 0}]
I could see the mistake i am doing is iterating lst2
inside the lst1
loop so the keys and values are assigned multiple times. But I need an output some thing like this
{{'a': 1, 'b': 8, 'c': 2}, {'d': 4, 'e': 3, 'a': 6}, {'g': 7, 'b': 9, 'i': 0}}
I want to preserve the structure of the list and create a keys and values for a dictionary, with which i could obtain the max key of the dictionaries. So my ultimate goal is to obtain this
"""
In the mydict
{{'a': 1, 'b': 8, 'c': 2},
{'d': 4, 'e': 3, 'a': 6},
{'g': 7, 'b': 9, 'i': 0}}
the key 'b' has max_value of 8,
the key 'a' has max_value of 6,
the key 'b' has max_value of 9.
#the output i need is [['b'],['a'],['b']]
"""
EDITED:
Thanks everyone for your answers, The iteration stops once its finds the max value how to get the keys of all with maximum values. For Eg:
lst1 = [['a','b','c'],['d','e','a'],['g','b','i']]
lst2 = [[1,8,2],[4,3,6],[7,9,9]]
needs output as
[['b'], ['a'], ['b','i']]
Upvotes: 0
Views: 209
Reputation: 30258
Your update means you will need to use a loop for efficiency, e.g.:
In []:
r = []
for xs, ys in zip(lst1, lst2):
m = max(ys)
r.append([x for x, y in zip(xs, ys) if y == m])
r
Out[]:
[['b'], ['a'], ['b', 'i']]
Here's the inefficient (multiple calls to max()
) comprehension version:
In []:
[[x for x, y in zip(xs, ys) if y == max(ys)] for xs, ys in zip(lst1, lst2)]
Out[]:
[['b'], ['a'], ['b', 'i']]
If you were really looking to create a dict
then I would reverse the relationship and have the number as the key, e.g.:
In []:
r = []
for xs, ys in zip(lst1, lst2):
d = {}
for x, y in zip(xs, ys):
d.setdefault(y, []).append(x)
r.append(d)
r
Out[]:
[{1: ['a'], 2: ['c'], 8: ['b']}, {3: ['e'], 4: ['d'], 6: ['a']}, {7: ['g'], 9: ['b', 'i']}]
Then to get the maximums:
In []:
[d[max(d)] for d in r]
Out[]:
[['b'], ['a'], ['b', 'i']]
Upvotes: 1
Reputation: 46523
To generate the dictionaries you could use
>>> [dict(z) for z in map(zip, lst1, lst2)]
[{'a': 1, 'b': 8, 'c': 2}, {'d': 4, 'e': 3, 'a': 6}, {'g': 7, 'b': 9, 'i': 0}]
Though, you don't have to create dict
objects if you just need the letters corresponding to maximum values:
>>> [max(z)[1] for z in map(zip, lst2, lst1)]
['b', 'a', 'b']
Upvotes: 3
Reputation: 250881
You can obtain the max_mydict
without an intermediate dictionary using zip
.
This basically find the index of max item in each sublist in list2
and then fetches the corresponding value from list1
.
>>> [a[max(range(len(b)), key=b.__getitem__)] for a, b in zip(lst1, lst2)]
['b', 'a', 'b']
In two steps:
>>> indices = (max(range(len(x)), key=x.__getitem__) for x in lst2)
>>> [x[next(indices)] for x in lst1]
['b', 'a', 'b']
Upvotes: 2
Reputation: 78546
You can use the following list comprehension. Zipping a second time the pair-wise lists from the first zip
and calling dict
on those:
l = [dict(zip(x, y)) for x, y in zip(lst1, lst2)]
print l
# [{'a': 1, 'c': 2, 'b': 8}, {'a': 6, 'e': 3, 'd': 4}, {'i': 0, 'b': 9, 'g': 7}]
And you can generate the max with:
print [[max(d, key=d.get)] for d in l]
# [['b'], ['a'], ['b']]
Upvotes: 1
Reputation: 71451
You can try this:
lst1 = [['a','b','c'],['d','e','a'],['g','b','i']]
lst2 = [[1,8,2],[4,3,6],[7,9,0]]
final = [{c:d for c, d in zip(a, b)} for a, b in zip(lst1, lst2))]
Upvotes: -1