What is a function parameter =[] for?

BartC bc at freeuk.com
Fri Nov 20 06:59:20 EST 2015


On 20/11/2015 01:05, Steven D'Aprano wrote:
> On Fri, 20 Nov 2015 04:30 am, BartC wrote:
>
>> On 19/11/2015 16:01, Steven D'Aprano wrote:
> [...]
>
>> The whole concept of 'mutable' default is alien to me. A default is just
>> a convenient device to avoid having to write:
>>
>>     fn(0) or fn("") or fn([])
>
> Says who?

People who want to avoid having to write:

      fn(0) or fn("") or fn([])

> Here's another use for function defaults, as static storage:
>
>
> # Ackermann's function
> def ack(m, n, _memo={}):
>      key = m, n
>      if key not in _memo:
>          if m==0: v = n + 1
>          elif n==0: v = ack(m-1, 1)
>          else: v = ack(m-1, ack(m, n-1))
>          _memo[key] = v
>      return _memo[key]
>
>
> This is a quick and easy way to memoise a function which would otherwise be
> horribly slow. And it only works because _memo is bound to a mutable object
> once, and once only.

We're arguing at cross-purposes then since you are obviously interested 
in these esoteric aspects, but all I want to do is avoid remembering a 
long list of defaults. Here's an example from another language, a 
function I'm working on at the minute:

function asklist(caption,&data,n=1, rows=10, width=50, flags="",
                  buttons=(), tablist=(), heading="")=

9 parameters, 7 of them optional. This is designed to be used with 
keyword arguments which is where the default values come into their own, 
as you don't need to remember positional order either.

Very basic stuff and very obvious what it's for. Notice some defaults 
are () (empty lists here), which are the ones that cause bother in Python.

(Here, however, the language doesn't like you doing in-place 
modification of a parameter unless the '&' is used, in which case you 
wouldn't be able to assign a default value such as () as you can only 
pass l-values.)


> def test(arg=[]):
>      arg.append(1)
>      return len(arg)
>
>
> The binding arg=[] is NOT inside the body of the function. Therefore, it is
> NOT executed repeatedly, but only once.

OK, so the "=" is misleading if not a lie.

>> So you didn't bother reading the LRM either!
>
> LRM? Left Right Manual?

Language Reference Manual.

>>>> That [] doesn't look like an object that could change.
>>>
>>> Of course it does.
>>
>> You've lost me know.

> a = []
> a.append(1)
>
> Are you shocked to learn that a is no longer an empty list?

No. But I would be surprised if, after this point, [] is no longer an 
empty list either!

No, forget that; by now, I wouldn't be surprised at all!

(That [] isn't changed is probably thanks to [] being implemented with 
the BUILD_LIST byte-code, which constructs a brand-new empty list each 
time. So the next time [] is used, it will be a different one from the 
one that has just been appended to.

In my language, a construct such as [10,20,30] is evaluated just once at 
start-up. If Python did the same, then I suspect such a literal could 
conceivably be changed if just "=" was used to ______[1] it to 'a'.)

([1] To avoid further argument, insert your own choice of jargon here.)

-- 
Bartc



More information about the Python-list mailing list