I wrote a small helper to collect tags. If I don’t pass an existing list, I want it to start a new one. Instead, the second call includes the tag from the first call:
def add_tag(tag, tags=[]):
# Add the requested tag and return the collection.
tags.append(tag)
return tags
# Make two calls without supplying a list.
first = add_tag("python")
second = add_tag("seo")
print(first) # Actual output: ['python', 'seo']
print(second) # Actual output: ['python', 'seo']
I expected first to contain only "python" and second to contain only "seo". What confuses me most is that first changes even though I never pass it into the second call.
How are Python default arguments evaluated, and how should I write this function if it needs to support both a fresh list and a caller-supplied list? In the second case, modifying the supplied list is intentional.