Converting List to Dict from different length of list in python

Question:

I try to convert 2 lists of different sizes to get a dictionary


listA = [123,456]
listB = ['B123', 'B123', 'C456', 'C456']

Output 
DictA = {123:['B123', 'C123'], 456: ['B456', 'C456']}
----------------------------------------------
listA = [123,456,789]
listB = ['B123' , 'C123', 'B456', 'C456', 'B789', 'C789']

Output
DictA = {123:['B123', 'C123'], 456: ['B456', 'C456'],  789: ['B789', 'C789']}

#My attempt:

[ {a: [b,c]} for (a, b,c) in zip(product(listA ,listB ))]

that is the code trying but it shows me error

Asked By: jhonatanalfred

||

Answers:

Here is a possible solution using a function with setdefault()

def create_dict(listA, listB):
    DictA = {} 
    for i in range(0, len(listB), 2):
        DictA.setdefault(listA[i//2], []).append(listB[i])
        DictA.setdefault(listA[i//2], []).append(listB[i+1])
    return DictA

listA = [123,456]
listB = ['B123', 'B123', 'C456', 'C456']
  
print(create_dict(listA, listB))

{123: ['B123', 'B123'], 456: ['C456', 'C456']}
listA = [123,456,789]
listB = ['B123' , 'C123', 'B456', 'C456', 'B789', 'C789']

print(create_dict(listA, listB))

{123: ['B123', 'C123'], 456: ['B456', 'C456'], 789: ['B789', 'C789']}
Answered By: Jamiu S.

Here is another way:

DictA = {}
val = iter(listB)
for key in listA:
    DictA[key] = [next(val), next(val)]

which from your inputs gives:

{123: ['B123', 'B123'], 456: ['C456', 'C456']}

{123: ['B123', 'C123'], 456: ['B456', 'C456'], 789: ['B789', 'C789']}
Answered By: user19077881

You can use enumerate() to get the in index of each key. You can use this to construct a slice from the list of values.

listA = [123,456]
listB = ['B123','B123','C456','C456']

{k:listB[2*i:2*i+2] for i, k in enumerate(listA)}

# {123: ['B123', 'B123'], 456: ['C456', 'C456']}

Alternatively, you can zip the list with an offset of itself skipping by two, then zip that with the keys:

pairs = map(list, zip(listB[::2], listB[1::2]))
dict(zip(listA, pairs))

# {123: ['B123', 'B123'], 456: ['C456', 'C456']}

If you are okay with tuples instead of lists, you can leave out the map():

pairs = zip(listB[::2], listB[1::2])
dict(zip(listA, pairs))

# {123: ('B123', 'B123'), 456: ('C456', 'C456')}
Answered By: Mark
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.