mstuebner
mstuebner

Reputation: 434

Dict comprehension, avoid data from being overwritten

On the input side I have a list of lists, i.e. as follows

[
  ['name1', 1,2,3,4],  # name, val1, val2, val3, val4
  ['name2', 4,3,6,2],
  ['name3', 9,6,4,9],
  ['name1', 10,3,12,4],
  ['name2', 1,4,3,2]
]

which is then converted to namedtuple (names above). To convert it to dict, I tried

result = {data.name: data for data in data_list}

but that overwrites the entry when the same name appears again. What I would like to achieve is, that the key/value is always

{'name': [[]]}

even if there is only one list per name. If there are multiple accourences of the same name, additional lists should be added instead of overwriting existing lists.

Can this be done in a dictionary comprehension?

Upvotes: 1

Views: 624

Answers (1)

Abhijit
Abhijit

Reputation: 63767

Can this be done in a dictionary comprehension? NO, unless you want to take an extra mile of sorting and grouping the data. That will steal readability from the code and its not worth the effort

Implementation

from operator import itemgetter
from itertools import groupby    
{ k : zip(*zip(*v)[1:])
      for k, v in groupby(sorted(data, key = itemgetter(0)), key = itemgetter(0))}

Output

{'name1': [(1, 2, 3, 4), (10, 3, 12, 4)],
 'name2': [(4, 3, 6, 2), (1, 4, 3, 2)],
 'name3': [(9, 6, 4, 9)]}

For cases like this you need to use defaultdict

Implementation

data = [
  ['name1', 1,2,3,4],  # name, val1, val2, val3, val4
  ['name2', 4,3,6,2],
  ['name3', 9,6,4,9],
  ['name1', 10,3,12,4],
  ['name2', 1,4,3,2]
]
data_dict = defaultdict(list)
for elem in data:
    data_dict[elem[0]].append(elem[1:])

Output

defaultdict(<type 'list'>, 
{'name1': [(1, 2, 3, 4), (10, 3, 12, 4)],
 'name2': [(4, 3, 6, 2), (1, 4, 3, 2)],
 'name3': [(9, 6, 4, 9)]})

Upvotes: 4

Related Questions