What is the pythonic way to avoid default parameters that are empty lists?
def my_func(working_list=None):
if working_list is None:
working_list = []
# alternative:
# working_list = [] if working_list is None else working_list
working_list.append("a")
print(working_list)
The docs say you should use None
as the default and explicitly test for it in the body of the function.
Most Pythonic way to convert None to an empty list in case a default argument is not passed in a Function?
You can check first if var
(1 and 2) are Not None
def my_func(var1=None, var2=None):
var1 = var1 if var1 is not None else []
var2 = var2 if var2 is not None else []
if not isinstance(var1, list):
var1 = [var1]
if not isinstance(var2, list):
var2 = [var2]
return var1 + var2
This will cover many cases, such as :
print(my_func(var2=[1, 2, 3]))
print(my_func(var1=None,var2=[1, 2, 3]))
print(my_func(var1=0,var2=[1, 2, 3]))
print(my_func(var1=False,var2=[1, 2, 3]))
print(my_func(var1='',var2=[1, 2, 3]))
[1, 2, 3]
[1, 2, 3]
[0, 1, 2, 3]
[False, 1, 2, 3]
['', 1, 2, 3]
Setting defaults for empty arguments (Python)
The first form as it reads easier. Without any specific context, you should explicitly test for the default value, to avoid potential truthiness issues with the passed in value.
def f(a, b=None):
if b is None:
b = []
pass
From PEP 8, Programming Recommendations:
Also, beware of writing if x when you really mean if x is not None --
e.g. when testing whether a variable or argument that defaults to None
was set to some other value. The other value might have a type (such
as a container) that could be false in a boolean context!
You can see examples of this approach throughout the cpython
repository:
- Lib/bdb.py
- Lib/argparse.py
- Lib/base64.py
How to type mutable default arguments
None
is not the only sentinel available. You can choose your own list value to use as a sentinel, replacing it (rather than None
) with a new empty list at run time.
_sentinel = []
def foo(bar: List[int]=_sentinel):
bar = [] if bar is _sentinel else bar
return sorted(bar)
As long as no one calls foo
using _sentinel
as an explicit argument, bar
will always get a fresh empty list. In a call like foo([])
, bar is _sentinel
will be false: the two empty lists are not the same object, as the mutability of lists means that you cannot have a single empty list that always gets referenced by []
.
How to stop function's list-type argument with default value from holding value on subsequent calls?
Default parameters are mutable in Python, you can think of them as belonging to the global scope. You want this:
def test(arg1=None):
if arg1 is None:
arg1 = []
arg1.append('bob')
return arg1
Default List Parameter doesn't Reset
No. It's a foible of Python that mutable object initializers do this. It's a better pattern to use None
and set the initial value in the method body:
def f(a=None):
if a is None:
a = []
print(a)
a += [1]
If you use pylint
, it provides a warning dangerous-default-value (W0102)
.
Why is the empty dictionary a dangerous default value in Python?
It's dangerous only if your function will modify the argument. If you modify a default argument, it will persist until the next call, so your "empty" dict will start to contain values on calls other than the first one.
Yes, using None
is both safe and conventional in such cases.
Related Topics
Performance of Pandas Apply VS Np.Vectorize to Create New Column from Existing Columns
Programming on Samsung Chromebook
The Correct Cmakelists.Txt File to Call a Maxon Libarary in a Python Script Using Pybind11
How to Create a Reference to a Variable in Python
Python Functions Call by Reference
How to Zip Two Differently Sized Lists, Repeating the Shorter List
Pandas Dataframe Get First Row of Each Group
Recursion and Return Statements
How to Access a Dictionary Element in a Django Template
Rendering Text with Multiple Lines in Pygame
How to Use the Same Python Virtualenv on Both Windows and Linux
Basic Python Hello World Program Syntax Error
Python Requests. 403 Forbidden
Combine Several Images Horizontally with Python
What Is the Fastest Way to Flatten Arbitrarily Nested Lists in Python
Importerror: No Module Named Pil
Why Isn't Pycharm's Autocomplete Working for Libraries I Install