Pass dictionaries in function as arguments

Question:

Im trying to create a function that take unknown number of arguments (dictionaries) to merge them in one. Here is my sketch:

weight = {"sara": 60, "nick": 79, "sem": 78, "ida": 56, "kasia": 58, "slava": 95}
height = { "a" : 1, "b": 2, "c":3 }
width = {"u": "long", "q": 55, "qw": "erre", 30: "34"}
a = {10:20, 20:"a"}

def merge(**dict):
    new_dict = {}
    for x in dict:
        for a, b in x.items():
            new_dict[a] = b

    return new_dict

print(merge(weight, height, width, a))

And I got error:

TypeError: merge() takes 0 positional arguments but 4 were given

Why?

Asked By: Pobaranchuk

||

Answers:

If you want to pass a list of dicts as a single argument you have to do this:

def foo(*dicts)

Anyway you SHOULDN’T name it *dict, since you are overwriting the dict class.


In Python you can pass all the arguments as a list with the * operator…

def foo(*args)

…and as a dict with the ** operator

def bar(**kwargs)

For example:

>>> foo(1, 2, 3, 4) # args is accessible as a list [1, 2, 3, 4]
>>> bar(arg1='hello', arg2='world') # kwargs is accessible as a dict {'arg1'='hello', 'arg2'='world'}

In your case you can edit the prototype of you function this way:

def merge(*dicts):
Answered By: FLAK-ZOSO

Change def merge(**dict): to def merge(*dict): and it is working. Avoid naming it dict since it is a keyword in python.

Answered By: raiyan22

First note: dict is a bad name for an argument as it is already the name of a type.

When you use ** in the argument list for a function it is slurping up any keyword arguments you haven’t explicitly listed. Similarly, a parameter with a single * is slurping up any extra positional arguments not explicitly named.

Consider:

>>> def foo(bar, **baz): return (bar, baz)
... 
>>> foo(42, wooble=42)
(42, {'wooble': 42})
>>> foo(bar=42, wooble=42)
(42, {'wooble': 42})
>>> foo(bar=42, wooble=42, hello="world")
(42, {'wooble': 42, 'hello': 'world'})
>>>

If you wish to take any number of dictionaries as arguments, you’d use:

def merge(*dicts):
    ...

As dicts will now slurp up any number of dictionaries passed in.

Answered By: Chris
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.