acb
acb

Reputation: 187

Create class objects with a dictionary as argument

In the next example, I have created a class Sample which accepts a dictionary of keyword arguments, like:

import numpy as np

class Sample:
    def __init__(self, **kwargs):
        self.A = kwargs['A']
        self.B = kwargs['B']
        self.C = kwargs['C']
        self.D = kwargs['D']
        self.E = kwargs['E']
        self.F = kwargs['F']
        self.G = kwargs['G']

and a function to create a list of class objects like:

def createSampleList (As, Bs, Cs, **kwargs):
    sampleList = []
    for A in As:
        for B in Bs:
            for C in Cs:
                addedkwargs = {'A': A, 'B': B, 'C': C}
                kwargs = dict(kwargs,**addedkwargs)
                sampleList.append (Sample (**kwargs))
    return sampleList

So far this function works fine if I give it a list of positional arguments like in the definition, so that

As = np.linspace (0, 3, 3)
Bs = np.linspace (0, 3, 4)
Cs = np.linspace (0, 3, 6)
D = 3
E = 5
F = 8
G = 9

sampleList = createSampleList (
                As, Bs, Cs, **{
                'D' : D,
                'E' : E,
                'F' : F,
                'G' : G,
            })

works as expected. For instace:

print(len(sampleList))
>>> 72

Now, what I would like is to be able to call the function createSampleList with a dictionary of variable length of keyword arguments. Say:

sampleList = createSampleList2 (
                {'A': As, 'B': Bs, 'C': Cs, 'D' : D }, **{
                    'E' : E,
                    'F' : F,
                    'G' : G,
            })

I have tried something like

def createSampleList2 (arrayDict, **kwargs):
    sampleList = []
    addedkwargs = dict()
    for key in arrayDict.keys():
        for value in arrayDict[key]:
            addedkwargs[key]= value
    kwargs = dict(kwargs,**addedkwargs)
    sampleList.append (Sample (**kwargs))
    return sampleList

but of course, this doesn't work. Any suggestions?

Upvotes: 1

Views: 108

Answers (1)

Tupteq
Tupteq

Reputation: 3095

If I understand correctly what you want is to create a product of given lists. If so, you can use Python's goods from itertools. Code below uses itertools.product to generate all possible combinations of lists' values. To make things simpler, non-iterable (e.g. simple numbers) are replaced by one-item-long lists:

from itertools import product

def createSampleList2(array_dict, **kwargs):
    sample_list = []
    keys = []
    values = []
    for k, v in array_dict.items():
        keys.append(k)
        try:
            iter(v)
            values.append(v)
        except TypeError:
            values.append([v])

    for value_set in product(*values):
        kw = dict(zip(keys, value_set))
        kw.update(kwargs)
        sample_list.append(Sample(**kw))
    return sample_list

This function will accept any combination of values and lists in array_dict. So all below are equivalent:

createSampleList2({"A": [1, 2], "B": [3, 4], "C": [5, 6]}, D=7, E=8, F=9, G=10)
createSampleList2({"A": [1, 2], "B": [3, 4], "C": [5, 6], "D": 7, "E": 8, "F": 9, "G": 10})

Upvotes: 1

Related Questions