Shouldn't lst point to [2], since after lst.append(x) lst not point to None anymore? Why the next execution still make lst point to none?
That is exactly what you prevent by using the lst=None, lst = [] if lst is None else lst construction. While the default arguments for the function are evaluated only once at compile time, the code within the function is evaluated each time the function is executed. So each time you execute the function without passing a value for lst, it will start with the default value of None and then immediately be replaced by a new empty list when the first line of the function is executed.
If you instead were to define the function like this:
def append_if_even(x, lst=[]):
if x % 2 ==0:
lst.append(x)
return lst
Then it would act as you describe. The default value for lst will be the same list (initially empty) for every run of the function, and each even number passed to the function will be added to one growing list.
For more information, see "Least Astonishment" and the Mutable Default Argument.
Answer from glibdud on Stack OverflowWhy no .get(idx[, default]) on python list??
list - Getting a default value on index out of range in Python - Stack Overflow
Initialise a list to a specific length in Python - Stack Overflow
Why isn't mutable default value (`field = List[int] = []`) a documented feature?
Hi all,
today it happened once again that I could really use a .get(idx[, default]) method on python lists. Here is a brief example why it could be useful (I know there are many alternative solutions to this specific problem here, so please focus generally on the idea of .get for lists).
file_name = 'test.png'
if '.' in file_name:
extension = file_name.rsplit('.', maxsplit=1)[1]
else:
extension = ''If we had such a method we could make the code much more concise
file_name = 'test.png'
extension = file_name.rsplit('.', maxsplit=1).get(1, '')I wonder why this useful method does not exist, especially since it is available for dicts.
dd = {'a': 'AAA'}
print(f"{dd['a']}; {dd.get('a')}; {dd.get('c')}; {dd.get('c', 'nothing here')}; ")
# AAA; AAA; None; nothing here;Thoughts / ideas why this is not present? Are there valid reasons not to have this method? Is it not available because someone has to invest the work to code it? How could something like this be initiated? :)
If the "default value" you want is immutable, @eduffy's suggestion, e.g. [0]*10, is good enough.
But if you want, say, a list of ten dicts, do not use [{}]*10 -- that would give you a list with the same initially-empty dict ten times, not ten distinct ones. Rather, use [{} for i in range(10)] or similar constructs, to construct ten separate dicts to make up your list.
list multiplication works.
>>> [0] * 10
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]