Watarap
Watarap

Reputation: 307

Creating dictionary from list of lists and obtain the maximum keys in python

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

Answers (5)

AChampion
AChampion

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

vaultah
vaultah

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

Ashwini Chaudhary
Ashwini Chaudhary

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

Moses Koledoye
Moses Koledoye

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

Ajax1234
Ajax1234

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

Related Questions