0

I have two lists:

list1 = ['670', '619', '524', '670', '693', '693', '693', '632', '671']
list2 = ['JAIPUR', 'MUMBAI', 'DELHI', 'UDAIPUR', 'GOA', 'GOA', 'GOA', 'LUCKNOW', 'JAIPUR']

I want to make a dictionary out of this. Please note the two lists exactly in the order that it should be mapped into. Like for key '670' value us 'JAIPUR' and so on.

But when I tried, it gives output as:

d = dict(zip(list1, list2))

{'670': 'UDAIPUR', '619': 'MUMBAI', '524': 'DELHI', '693': 'GOA', '632': 'LUCKNOW', '671': 'JAIPUR'}

It takes only the latest value if multiple values are found for a single key. However what I want is multiple values for a single key like 670 should have:

'670': ['JAIPUR', 'UDAIPUR']

Can anyone help.

Marvin
  • 421
  • 1
  • 5
  • 15
  • 1
    `dict` objects associate key-value pairs where the keys are unique. However, your values can be containers themselves, so, for example a `list` or a `tuple`. – juanpa.arrivillaga Oct 24 '17 at 10:24
  • 2
    Is there a logic? In the example shared, you have equal number of elements in list1 and list2. – Parijat Purohit Oct 24 '17 at 10:24
  • 2
    How would you determine which element(s) from `list2` should be mapped to each key from `list1`? Update your question and you might get more helpful answers. – TeaPow Oct 24 '17 at 10:26

3 Answers3

5

Use defaultdict :

>>> from collections import defaultdict
>>> d = defaultdict(list)
>>> for i,key in enumerate(list1): 
        if list2[i] not in d[key]:            #to add only unique values (ex: '693':'goa')
            d[key].append(list2[i]) 

>>> d
=> defaultdict(<class 'list'>, {'670': ['JAIPUR', 'UDAIPUR'], '619': ['MUMBAI'], 
               '524': ['DELHI'], '693': ['GOA'], '632': ['LUCKNOW'], '671': ['JAIPUR']})
Kaushik NP
  • 6,733
  • 9
  • 31
  • 60
  • 1
    This is exactly what I was looking for. Also removes any duplicate values. Perfect ! Thank you – Marvin Oct 24 '17 at 11:36
  • @VinnyKaur : glad to help – Kaushik NP Oct 24 '17 at 11:49
  • @mrCarnivore : `defaultdict` is nothing but a wrapper around `dict` , and so it offers a few extra functionalities, but all its basic structuring from `dict` are intact too. – Kaushik NP Oct 24 '17 at 12:43
  • @KaushikNP can you please explain the part `enumerate(list1)` does here – Marvin Oct 25 '17 at 12:26
  • @VinnyKaur : its used to access both `Index` along with the `elements` when iterating over the `list` here. You could go through : [Iterate a list with indexes in Python](https://stackoverflow.com/questions/126524/iterate-a-list-with-indexes-in-python/126533#126533) for better example on how its used. – Kaushik NP Oct 25 '17 at 15:30
2

What you need is grouping by the list1 items. Use collections.defaultdict object:

import collections

list1 = ['670', '619', '524', '670', '693', '693', '693', '632', '671']
list2 = ['JAIPUR', 'MUMBAI', 'DELHI', 'UDAIPUR', 'GOA', 'GOA', 'GOA', 'LUCKNOW', 'JAIPUR']
result = collections.defaultdict(list)

for t in zip(list1, list2):
    result[t[0]].append(t[1])

print(dict(result))

The output:

{'524': ['DELHI'], '671': ['JAIPUR'], '632': ['LUCKNOW'], '670': ['JAIPUR', 'UDAIPUR'], '619': ['MUMBAI'], '693': ['GOA', 'GOA', 'GOA']}
RomanPerekhrest
  • 88,541
  • 4
  • 65
  • 105
  • how does it identify list1 as t[0] and list2 as t[1]. Apologies if the question sounds silly, but python is new for me. – Marvin Oct 24 '17 at 11:21
  • 1
    @VinnyKaur, `zip()` function generates a list/generator of tuples where each tuple contains consecutive values from all passed iterables, like `(670, 'JAIPUR'), (619, 'MUMBAI') ...` – RomanPerekhrest Oct 24 '17 at 11:28
0

Since dicts can not have more than one element with the same key the newer values for that key that are assigned to a dict overwrite the older ones.

So with this code it works:

list1 = ['670', '619', '524', '670', '693', '693', '693', '632', '671']
list2 = ['JAIPUR', 'MUMBAI', 'DELHI', 'UDAIPUR', 'GOA', 'GOA', 'GOA', 'LUCKNOW', 'JAIPUR']

def extendDictValue(d, key, value):
    if key in d:
        d[key].append(value)
    else:
        d[key] = [value]

d={}
for key, value in zip(list1, list2):
    extendDictValue(d, key, value)

print(d)
mrCarnivore
  • 4,638
  • 2
  • 12
  • 29