anna
anna

Reputation: 137

Loop through Dictionary and add values

I am trying to add values for duplicate keys in a dictionary. I am not sure why my code isn't working.

d = {'inds': [], 'vals': []}
d['inds'] = [0,   3,   7,   3,   3,   5, 1]
d['vals'] = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0]

I would like to get a list with the added values as result at index 3 and 0 for an index that doesn't exist:

desired_output=[1.0, 7.0, 0.0, 11.0, 0.0, 6.0, 0.0, 3.0]

My code: I am making list of zeros and adding dictionary in a loop.

d = {'inds': [], 'vals': []}
d['inds'] = [0,   3,   7,   3,   3,   5, 1]
d['vals'] = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0]

length=len(d['inds'])

a=[0]*(length)

for key,val in d.items():
    a[key]= a[key] + d[val]

It's throwing an error: TypeError: list indices must be integers or slices, not str

Appreciate your help.

Upvotes: 2

Views: 653

Answers (3)

Ajax1234
Ajax1234

Reputation: 71451

Using a shorter, though not as effecient, list comprehension:

d = {}
d['inds'] = [0,   3,   7,   3,   3,   5, 1]
d['vals'] = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0]
new_d = [0 if i not in d['inds'] else dict(zip(d['inds'], d['vals']))[i] for i in range(max(d["inds"])+1)]

Output:

[1.0, 7.0, 0, 5.0, 0, 6.0, 0, 3.0]

Upvotes: 1

Jean-François Fabre
Jean-François Fabre

Reputation: 140168

you don't even need a dictionary here (but I'll leave it in). just zip indices & values and add to your zeroed list. Also the length of your result list is incorrect. Compute it using max of the indices plus one:

d = {}
d['inds'] = [0,   3,   7,   3,   3,   5, 1]
d['vals'] = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0]

result = [0]*(max(d["inds"])+1)
for a,b in zip(d['inds'],d['vals']):
    result[a] += b

result:

[1.0, 7.0, 0, 11.0, 0, 6.0, 0, 3.0]

Upvotes: 8

John Kugelman
John Kugelman

Reputation: 361585

for key, val in d.items():

This loops over the items at the top-level of d: first key='inds' and val=[0, 3, 7, 3, 3, 5, 1], and then key='vals' and val=[1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0]. But you're looking for key to take on the values 0, 3, 7, 3, etc., and for val to be 1.0, 2.0, 3.0, etc.

To loop over the indices in d['inds'] and the values in d['vals'], use zip. It will pull one item at a time from each sublist in parallel.

for key, val zip(d['inds'], d['vals']):

Upvotes: 3

Related Questions