Live data from Hacker News

A few things to remember while coding in Python

satyajit.ranjeev.in

111–120 of 146 posts

Re: A few things to remember while coding in Python

#111
post #109
post #5

It's worth explaining why mutable defaults are bad. The problem with mutable defaults is that they are evaluated once only when the function is defined. Each time the function is called you'll be using the same mutable variable that was created during function definition.

> It's worth explaining why mutable defaults are bad They can also be good. Here's an example from the Reddit discussion, showing how a mutable default can be used to very neatly and cleanly add memorization to a function: def fib(n, m={}): if n not in m: m[n] = 1 if n

Is that clean and neat, or weird and inscrutable? Will it be clear to /anyone/ reading that code what it's doing?

Re: A few things to remember while coding in Python

#112
post #109

Earlier quoted context omitted.

> It's worth explaining why mutable defaults are bad They can also be good. Here's an example from the Reddit discussion, showing how a mutable default can be used to very neatly and cleanly add memorization to a function: def fib(n, m={}): if n not in m: m[n] = 1 if n

Is that clean and neat, or weird and inscrutable? Will it be clear to /anyone/ reading that code what it's doing?

I agree with your sceptisism. This is misusing a language feature, a better approach is using a decorator.

Re: A few things to remember while coding in Python

#113

Earlier quoted context omitted.

Sure it is! And in Python 3 there's the ,_*= operator, similar to lisp's car: varname ,_*= [1, 2, 3] # varname == 1

HN isn't the place for facetiousness.

Apparently it isn't the place for humour either.

Re: A few things to remember while coding in Python

#115
post #21
post #5

It's worth explaining why mutable defaults are bad. The problem with mutable defaults is that they are evaluated once only when the function is defined. Each time the function is called you'll be using the same mutable variable that was created during function definition.

I came here looking for an explanation for this, so thanks. To the curious - SO has an explanation of why Python was designed like this, which I found interesting: http://stackoverflow.com/questions/1132941/least-astonishmen...

I don't buy this explanation.

Actually, this is not a design flaw, and it is not because of internals, or performance. It comes simply from the fact that functions in Python are first-class objects, and not only a piece of code.

Why in Common Lisp defaults behave the way one would expect, then? Functions are also first class, but defaults are evaluated at every call.

Re: A few things to remember while coding in Python

#116
post #109
post #5

It's worth explaining why mutable defaults are bad. The problem with mutable defaults is that they are evaluated once only when the function is defined. Each time the function is called you'll be using the same mutable variable that was created during function definition.

> It's worth explaining why mutable defaults are bad They can also be good. Here's an example from the Reddit discussion, showing how a mutable default can be used to very neatly and cleanly add memorization to a function: def fib(n, m={}): if n not in m: m[n] = 1 if n

I blogged about this, and other uses for mutable default arguments (with tongue somewhat in cheek) a few weeks ago: http://inglesp.github.com/2012/03/24/mutable-default-argumen...

Re: A few things to remember while coding in Python

#117
post #109

Earlier quoted context omitted.

> It's worth explaining why mutable defaults are bad They can also be good. Here's an example from the Reddit discussion, showing how a mutable default can be used to very neatly and cleanly add memorization to a function: def fib(n, m={}): if n not in m: m[n] = 1 if n

Is that clean and neat, or weird and inscrutable? Will it be clear to /anyone/ reading that code what it's doing?

I'm a Python newbie, and that code was immediately clear and obvious to me when I read it.

I won't say it would be clear anyone that reads it, because we live in a world where people who claim to be programmers can't do fizz buzz.

Re: A few things to remember while coding in Python

#118
post #63

Earlier quoted context omitted.

Well, yes, but I'd also like to think that code should raise the level of the programmers reading it...You should avoid gratuitous complexity I have a different set of policies than most programmers, which arises from my observation that our field's priorities are out of whack with the actual cost-benefit. Our greatest costs involve understanding systems, so our first priority should typically be to produce readable…

I agree strongly. It amazes me that in the ugly vs. beautiful category, the article uses this as the beautiful: return [i/2 for i in nums if not i % 2] "not i % 2"? That's beautiful? We do a division and ask whether the remainder is not true? What does it mean for a remainder of a division to be not true? Is sqrt(3) untrue? Is 17 not yellow? Is this really the clearest way to say even number? Yes, after years of work…

I agree, I wondered about that same snippet.

And I tested with the `timeit` module, there's not really much of a performance difference either (although the version with `not` is slightly faster, it's just by less than a percent or so).

Re: A few things to remember while coding in Python

#119
Satyajit Ranjeev:

Since this is posted by the you as the author, I'll comment here: some JavaScript is running on page load that blanks the entire page in Safari and iCab on iPad, making the page turn white except for the bullet symbols, and making the article unreadable.

I was able to read it only by disabling JavaScript or parsing it with Readability. (Both disable my ability to comment about this bug there.)

Re: A few things to remember while coding in Python

#120
post #115
post #21

Earlier quoted context omitted.

I came here looking for an explanation for this, so thanks. To the curious - SO has an explanation of why Python was designed like this, which I found interesting: http://stackoverflow.com/questions/1132941/least-astonishmen...

I don't buy this explanation. Actually, this is not a design flaw, and it is not because of internals, or performance. It comes simply from the fact that functions in Python are first-class objects, and not only a piece of code. Why in Common Lisp defaults behave the way one would expect, then? Functions are also first class, but defaults are evaluated at every call.

I don't know CL, but in python function definitions can be executed multiple times... at the top level this happens at module import, so it ends up being only once. But in nested definitions, e.g.

   def foo():
      def bar():
         ...
      return bar
   foo() == foo() # false
Two different function objects are created. If, in the above examle, bar took a pram thelist=[], each call to foo would produce a bar function with a different list instance for thelist. The default values can be read as expressions passed to the function object constructor, rather than a bit of code to be evaluated each function run.

I don't know how CL works in this regard, nor do I know which is better or worse. I think the explanation linked did a terrible job conflating first class functions with execution and runtime models. Some of the answers below it explain better tho. :)

Post reply on HN