Tulintoy
Tulintoy

Reputation: 19

How to create a dictionary from a list of class instances, using one of the attributes as the key.

I have a function (createList) that reads from a text file and creates class instances from every line in the file. This function then returns a list of class instances. Now what I want to do is create a dictionary from this list using one of the attributes as the key.

def createDict():
    list = createList()
    fileAsDict = {}
    for i in list:
        fileAsDict[i.name] = i

    return fileAsDict

This seemed to be a simple solution, but I noticed multiple instances on the text file have the same "key". The code I've written doesn't handle this and overrides the value for a key every time it finds the same i.name. What I want is for it to store the values on a list so when I call on the key, it prints all the class instances with that attribute.

I found a few tips like

for key, val in l:
d.setdefault(key, []).append(val)

But I don't know how to implement that to my code.

Upvotes: 1

Views: 6704

Answers (1)

Chris
Chris

Reputation: 22953

You were on the right track using setdefault. You simply need to replace key with i.name. Here is a simple example implementation showing the logic:

>>> # create a dummy class, so we can put some
>>> # instances in a list
>>> class Dummy:
    def __init__(self, name):
        self.name = name


>>> # create a list with Dummy() class instances. Uh oh! some of them have the
>>> # same value for self.i
>>> classes = [Dummy('a'), Dummy('b'), Dummy('b'), Dummy('c'), Dummy('d')]
>>> 
>>> # now we'll create the dictionary to hold the class instances.
>>> classes_dict = {}
>>> 
>>> # Here we are iterating over the list. For every element in the list,
>>> # we add to the dict using setdefault(). This means that if the element
>>> # key is already in the dict, we append it to the key's list. Otherwise,
>>> # we create a key with a new, empty list.
>>> for each_class in classes:
    classes_dict.setdefault(each_class.name, []).append(each_class)


>>> # final result
>>> classes_dict {'a': [<__main__.Dummy object at 0x0000020B79263550>],
 'b': [<__main__.Dummy object at 0x0000020B792BB1D0>,
     <__main__.Dummy object at 0x0000020B792BB320>],
 'c': [<__main__.Dummy object at 0x0000020B792BB358>],
 'd: [<__main__.Dummy object at 0x0000020B792BB390>]}
>>> 

Upvotes: 1

Related Questions