pass multiple dictionaries to a function as an argument
Asked Answered
I

10

12

I have two dictionaries:

SP = dict{'key1': 'value1','key2': 'value2'}
CP = dict{'key1': 'value1','key2': 'value2'}

I have a function that would like to take those two dictionaries as inputs, but I don't know how to do that.

I'd tried:

def test(**SP,**CP):
    print SP.keys(),CP.keys()

test(**SP,**CP)

The real function will be more complicated with lots of modification of two dictionaries. But the simple test function doesn't work for me :(

Ivied answered 22/6, 2014 at 21:8 Comment(0)
H
10

If you just want to take two dictionaries as separate arguments, just do

def test(SP, CP):
    print SP.keys(),CP.keys()

test(SP, CP)

You only use ** when you want to pass the individual key/value pairs of a dictionary as separate keyword arguments. If you're passing the whole dictionary as a single argument, you just pass it, the same way you would any other argument value.

Hynes answered 22/6, 2014 at 21:9 Comment(0)
A
6

When you want to pass two different dictionaries to a function that both contains arguments for your function you should first merge the two dictionaries.

For example:

dicA = {'spam':3, 'egg':4}
dicB = {'bacon':5, 'tomato':6}

def test(spam,tomato,**kwargs):
    print spam,tomato

#you cannot use:
#test(**dicA, **dicB)

So you have to merge the two dictionaries. There are several options for this: see How to merge two Python dictionaries in a single expression?

dicC = dicA.copy()
dicC.update(dicB)

#so now one can use:
test(**dicC)

>> 3 6
Altis answered 30/3, 2016 at 13:51 Comment(0)
R
6

You can combine both dictionaries (SP and CP) in a single one using the dict constructor.

test(**dict(SP,**CP))
Refugiorefulgence answered 4/1, 2018 at 11:11 Comment(1)
Or test(**{**SP,**CP}) if you prefer. (possibly because you're allergic to asymmetry or to the word dict.)Entomostracan
U
1

Why it doesn't work:

In Python the "**" prefix in the arguments is to make one argument capture several other ones. For example:

SP = {'key1': 'value1','key2': 'value2'}

def test(**kwargs):              #you don't have to name it "kwargs" but that is
    print(kwargs)                #the usual denomination


test(**SP)
test(key1='value1', key2='value2')

The two call on the test function are exactly the same

Defining a function with two ** arguments would be ambiguous, so your interpreter won't accept it, but you don't need it.

How to make it work:

It is not necessary to use ** when working with normal dictionary arguments: in that case you can simply do:

SP = {'key1': 'value1','key2': 'value2'}
CP = {'key1': 'value1','key2': 'value2'}

def test(SP,CP):
    print(SP)
    print(CP)

test(SP,CP)

Dictionaries are objects that you can directly use in your arguments. The only point where you need to be careful is not to modify directly the dictionary in argument if you want to keep the original dictionnary.

Urticaceous answered 15/2, 2019 at 23:47 Comment(0)
M
0

Use *args to take multiple arguments.

SP={'key1':'value1','key2':'value2'}  `dict{'key1':'value1','key2':'value2'}` 
CP={'key1':'value1','key2':'value2'}

def test(*args):
    for arg in args:
        print arg.keys(),

test(SP,CP)
['key2', 'key1'] ['key2', 'key1']
Millicentmillie answered 22/6, 2014 at 21:14 Comment(0)
P
0
def merge(*d):
   r={}
   for x in d:r.update(x)
   return r

d1={'a': 1, 'b': 2}
d2={'y': 4, 'x': 3}

def f(**k): print(k)

f(**merge(d1,d2))   # you're on your own if keys repeat unintentionally

gives {'a': 1, 'y': 4, 'b': 2, 'x': 3}

Photofluorography answered 20/8, 2016 at 15:17 Comment(0)
M
0

If you want to avoid combining the dictionaries, then provide them as arguments rather than keyword arguments, and set their defaults to something (such as None), and convert None to {} and otherwise copy the dictionary.

SP = {'key1': 'value1', 'key2': 'value2'}
CP = {'key1': 'value3', 'key2': 'value4'}

def test(SP=None, CP=None):
    SP = {} if SP is None else SP.copy()
    CP = {} if CP is None else CP.copy()
    # Now use SP and CP as keyword arguments to other functions
    foo(**SP)
    baz(**CP)

def foo(**kws):
    print(kws.items())

def baz(**kws):
    print(kws)

test(SP=SP)
test(CP=CP)
test(SP, CP)

I often do this when passing keyword arguments to different plotting functions called within my function, and I send different dictionaries of keyword arguments to these plotting functions.

Mohair answered 10/2, 2017 at 15:30 Comment(0)
L
0

TLDR: Pass a dictionary of dictionaries

I found myself with same problem and i can't merge dictionaries because I wanted to keep the contents of each dictionary apart inside the called function. Solution I found is to use a nested dictionary.

    args = {}
    args['SP'] = dict{'key1': 'value1','key2': 'value2'}
    args['CP'] = dict{'key1': 'value1','key2': 'value2'}

    test(**args)

    def test (**kwargs):
        arg_sp = kwargs.get('SP')
        arg_cp = kwargs.get('CP')
Literator answered 2/8, 2018 at 19:15 Comment(0)
B
0

As usually the kwargs is used to add countless function parameters, therefore it is somehow unusual to use two kwargs at the same time. But another way around, two dictionaries can be parameterized as usual parameters. Thus a little bit of change in the code snipet might be helpful:

SP = {'key1': 'value1','key2': 'value2'}
CP = {'key1': 'value1','key2': 'value2'}
def test(SP,CP):
    print(SP.keys(),CP.keys())

test(SP,CP)

Output: dict_keys(['key1', 'key2']) dict_keys(['key1', 'key2'])

Bahuvrihi answered 18/12, 2021 at 9:53 Comment(0)
R
0

You can pass only a single dictionary to the **kwargs but if you want to pass a second dictionary you can simply pass it as a simple variable e.g.

SP = dict({"key1": "value1", "key2": "value2"})
CP = dict({"key1": "value1", "key2": "value2"})


def test(SP, **CP):
    # print(SP.keys(), CP.keys())
    print("Keys of Dictionary 1: ", SP.keys())
    print("Keys of Dictionary 2: ", CP.keys())


test(SP, **CP)
Rebatement answered 10/9, 2022 at 6:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.