Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the most Pythonic way to use an empty dictionary as a default argument?

Tags:

python

Using default arguments of the form x={} usually does not accomplish the intended purpose in Python, since default arguments are bound when a function is defined, not called.

The convention seems to be to set mutable objects as default arguments with x=None and then check x is None to assign the proper default when the function is called.

So if I would like to cast x to a dictionary that is by default empty, I would use something like the following:

def f(x=None):
    x = dict(x) if x is not None else {}

However, since dict can take any iterable, I could also write this more succinct version:

def f(x=()):
    x = dict(x)

Which of these is the "right" approach?

like image 500
shoyer Avatar asked Dec 10 '12 06:12

shoyer


People also ask

How do you pass empty dictionary?

To initialize a dictionary to an empty dictionary, use the Clear() method. It clears the dictionary and forms it as empty.

How do you pass an empty dictionary in Python?

In Python to create an empty dictionary, we can assign no elements in curly brackets {}. We can also create an empty dictionary by using the dict() method it is a built-in function in Python and takes no arguments.

What is a mutable default argument?

In Python, when passing a mutable value as a default argument in a function, the default argument is mutated anytime that value is mutated. Here, "mutable value" refers to anything such as a list, a dictionnary or even a class instance.

What is the default value of dictionary in Python?

default defaults to None . Return the value for key if key is in the dictionary, else default . If default is not given, it defaults to None , so that this method never raises a KeyError . In the above code, you use .


1 Answers

The idiomatic style is to not cast to dict; that way someone could use any object that implements the correct mapping methods.

So, the most pythonic method is to use:

def f(x=None):
    if x is None:
        x = {}

and then just use mapping methods.

So, you generally should not cast arguments to a dict. You state your API accepts a mapping object instead, and expect callers to do the casting.

The only reason to accept both a dict and an iterable is when you want to support ordered key-value pairs where duplicate keys are allowed, such as for the urllib.urlencode function. In such a case a dict cannot retain that information, and that method does not cast the iterable to a dict, but rather uses the dict as an iterable.

like image 135
Martijn Pieters Avatar answered Sep 22 '22 05:09

Martijn Pieters