Home > database >  Why does passing a dictionary as part of *args give us only the keys?
Why does passing a dictionary as part of *args give us only the keys?

Time:11-19

The setup

Let's say I have a function:

def variadic(*args, **kwargs):
    print("Positional:", args)
    print("Keyword:", kwargs)

Just for experiment's sake, I call it with the following:

variadic({'a':5, 'b':'x'}, *{'a':4, 'b':'y'}, **{'a':3, 'b':'z'})

Output:

Positional: ({'a': 5, 'b': 'x'}, 'a', 'b')
Keyword: {'a': 3, 'b': 'z'}

The problem

I don't have an issue with the keyword arguments.

For the positional ones, however, we get the tuple ({'a': 5, 'b': 'x'}, 'a', 'b'). I understand why we get the first element ({'a': 5, 'b': 'x'}), but I am surprised that we are getting only the keys (a, b) from {'a':4, 'b':'y'}. I don't understand why this is happening. I think I expected an error from passing a dictionary to *args instead.

Possible answers?

I have not been able to find an answer, but suspect that when parsing *args Python does something along the lines:

for arg in args:
    do something

and since we passed a dictionary, and iterating over a dictionary like this (as opposed to d.items()) gives us only the keys, we just get the keys. Can anyone confirm that or clear up why this is happening?

CodePudding user response:

In a function call, an argument prefixed with a * must be an iterable value. Each value produced by iterating over the argument is provided to the function as a separate positional argument. (Note that this is independent of a paraemter prefixed with a *, which collects positional arguments not assigned to any other parameter into a tuple.)

Values of type dict are iterable; the iterator for a dict yields the keys of the dict.

  • Related