Adding to the values ​​in the dictionary from two lists of different lengths

I have four lists that look like this:

lista = [['l', 'k'],['e', '3'],['c', 'k'],['x', 'i'],['d', 'f']] listanum = [1,2,3,4,5] listb = [['a', 'k'],['c', 'm'],['v', 'f']] listbnum = [1,3,4] 

lista and listanum sync, listb and listbnum too. I want to make a dictionary where the keys are elements in listanum and the values ​​are elements in lista and listb , the result will be:

 di = {1: [['l','k'],['a', 'k']], 2: [['e', '3'],[]], 3:[['c','k'],['c', 'm']], 4: [['x', 'i'],['v', 'f']], 5: [['d', 'f'][]] } 

therefore, if there is no value in the list for the number in listanum, the second list in the dictionary values ​​is empty.

I tried this:

 di = {} for i in xrange(len(lista)): pos = listanum[i] if pos not in di: di[pos] = [[],[]] di[pos][0].append(lista[i]) if i in listbnum: di[pos][1].append(listb[i]) 

but get this error message: 'IndexError: list index out of range' . I can’t understand why it is out of range.

+4
source share
2 answers

Replace the elements and use the collections.defaultdict default list s values:

 from itertools import chain from collections import defaultdict di = defaultdict(list) for key, value in chain(zip(listanum, lista), zip(listbnum, listb)): di[key].append(value) 

I used chain to simplify the loop for both sets of key-value pairs; this works in both Python 2 and 3. If this is just Python 2 code, you can use + to combine the two lists.

Output from pprint and switching to a regular dict to simplify printing:

 >>> pprint(dict(di)) {1: [['l', 'k'], ['a', 'k']], 2: [['e', '3']], 3: [['c', 'k'], ['c', 'm']], 4: [['x', 'i'], ['v', 'f']], 5: [['d', 'f']]} 

This does not create empty lists for the second set; if you have empty lists, you are limited to creating two separate dictionaries and then merging them:

 dicta = dict(zip(listanum, lista)) dictb = dict(zip(listbnum, listb)) di = {k: [dicta.get(k, []), dictb.get(k, [])] for k in dicta.viewkeys() | dictb.viewkeys()} 

for Python 2, for Python 3 use .keys() instead of .viewkeys() to create:

 >>> pprint(di) {1: [['l', 'k'], ['a', 'k']], 2: [['e', '3'], []], 3: [['c', 'k'], ['c', 'm']], 4: [['x', 'i'], ['v', 'f']], 5: [['d', 'f'], []]} 

In particular, for your code, you confuse i (the index in lista ) with pos :

  if i in listbnum: di[pos][1].append(listb[i]) 

For i = 4 , i in listbnum is True , but listb[4] does not exist. Your code also tried adding lists from lista and listb , which would not lead to the correct output.

Modify your version a listb using a separate loop for listb / listbnum :

 di = {} for i, pos in enumerate(listanum): if pos not in di: di[pos] = [[],[]] di[pos][0][:] = lista[i] for i, pos in enumerate(listbnum): di[pos][1][:] = listb[i] 
+5
source
 In [7]: da = dict(zip(listanum, lista)) In [8]: db = dict(zip(listbnum, listb)) In [9]: {k:[da.get(k,[]), db.get(k,[])] for k in set(listanum + listbnum)} Out[9]: {1: [['l', 'k'], ['a', 'k']], 2: [['e', '3'], []], 3: [['c', 'k'], ['c', 'm']], 4: [['x', 'i'], ['v', 'f']], 5: [['d', 'f'], []]} 
+5
source

All Articles