Adding to values in a dictionary from two lists of different length

list, python

Solution

Zip the items, and use `collections.defaultdict` to default the values to `list`s:

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 make looping over both sets of key-value pairs easier; this works in both Python 2 and 3. If this is Python 2 only code, you could use `+` to concatenate the two lists.

Output with `pprint` and converting back to a regular `dict` to make printing easier:

>>> 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 to have empty lists, you are limited to building two separate dictionaries then merging those:

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 produce:

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

Specifically, for your code, you confused `i` (the index into `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 to append the lists from `lista` and `listb`, which would not result in the correct output.

Altering your version a little to work, using a separate loop for the `listb`/`listbnum` lists:

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]

Problem

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` are synchronized, `listb` and `listbnum` too. I want to make a dictionary where the keys are the items in `listanum` and the values are items in `lista` and `listb`, the outcome would be: ``` di = {1: [['l','k'],['a', 'k']], 2: [['e', '3'],[]], 3:[['c','k'],['c', 'm']], 4: [['x', 'i'],['v', 'f']], 5: [['d', 'f'][]] } ``` so if there is no value for a number in listanum in listb, the second list in the dictionarys values is empty. I have 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 cant see why it is out of range???

Original source