Why is defaultdict creating an array for my values?

Question:

I’m creating a defaultdict from an array of arrays:

>>> array = [['Aaron','1','2'],['Ben','3','4']]
>>> d = defaultdict(list)
>>> for i in array:
...     d[i[0]].append({"num1":i[1],"num2":i[2]})

My expected outcome is:

>>> d
defaultdict(<type 'list'>, {'Aaron': {'num1': '1', 'num2': '2'}, 
'Ben': {'num1': '3', 'num2': '4'}})

But my outcome is:

>>> d
defaultdict(<type 'list'>, {'Aaron': [{'num1': '1', 'num2': '2'}], 
'Ben': [{'num1': '3', 'num2': '4'}]})

It is as if defaultdict is trying to keep my values in an array because that is the source list!

Anyone know what’s going on here and how I can get my expected outcome?

Asked By: RonnyKnoxville

||

Answers:

When you call this:

d = defaultdict(list)

It means that if you attempt to access d['someKey'] and it does not exist, d['someKey'] is initialized by calling list() with no arguments. So you end up with an empty list, which you then append your dictionary to. You probably want this instead:

d = defaultdict(dict)

and then this:

for a, b, c in array: 
  d[a].update({"num1": b, "num2": c})
Answered By: g.d.d.c

You need a plain dictionary here, not a defaultdict:

d = {}
for name, num1, num2 in array:
    d[name] = {"num1": num1, "num2": num2}

or using a dictionary comprehension

d = {name: {"num1": num1, "num2": num2} for name, num1, num2 in array}

This code results in d being

{'Aaron': {'num1': '1', 'num2': '2'}, 'Ben': {'num1': '3', 'num2': '4'}}

A defaultdict(list) creates an empty list if you access a non-existent key.

Answered By: Sven Marnach

Do

from collections import defaultdict
d = defaultdict(list)
Answered By: Charlie Parker