Reputation: 27
I am writing an auxiliary python function that takes as arguments two lists and iterates over them. Often the second list needs to be an array of zeros with the same length as the first. I would like to set up the second list as a keyword argument and assign it this default value.
def iterate(list_a, list_b = np.zeros((len(list_a),), dtype=int)):
for a, b in zip(list_a, list_b):
# do something with a and b
However, I get an error that list_a is not defined, suggesting I can't perform self-referencing computations in the brackets when defining a function. An obvious solution is to pick a special default value for list_b and, if left unchanged when calling the function, change it to a list of zeros with an if statement:
def iterate(list_a, list_b = 'zeros'):
if list_b == 'zeros':
list_b = np.zeros((len(list_a),), dtype=int)
for a, b in zip(list_a, list_b):
# do something with a and b
This solution doesn't seem very pythonic to me and I am wondering if there is a better practice for going about it.
I am keeping it general on purpose but I can give more detail about what my function does if needed.
Upvotes: 2
Views: 431
Reputation: 207
No, this can't be done, but you've basically solved the issue in the usual way.
Usually in this case people will set the default values to None
and do the same thing (just because this is less wierd with typing and thus linting - the function accepts either an array or nothing rather than an array or a string.)
In terms of usability, you can tell the user what the default value is effectively doing in the doc script.
def iterate(list_a, list_b=None):
'list_b defaults to zero array of size a'
if not list_b:
list_b = np.zeros((len(list_a),), dtype=int)
for a, b in zip(list_a, list_b):
# do something with a and b
The reason it's not possible is because the list_a
variable hasn't been created yet when you call it in the same line, since the python interpreter goes line by line.
Upvotes: 1