Live data from Hacker News

A few things to remember while coding in Python

satyajit.ranjeev.in

61–70 of 146 posts

Re: A few things to remember while coding in Python

#61

Earlier quoted context omitted.

You could also use the ,= operator, of course: varname ,= [...]

It appears to me that there is actually no such operator in Python; cf. http://docs.python.org/reference/simple_stmts.html#augmented... Superficially it looks like an operator, but I suspect that's merely because of whitespace freedom; i.e., a, = [0] is equivalent to a,=[0] and a ,= [0].

  Sure it is! And in Python 3 there's the ,_*= operator, similar to lisp's car:

  varname ,_*= [1, 2, 3] # varname == 1

Re: A few things to remember while coding in Python

#62
post #18

Earlier quoted context omitted.

That seems like decidedly unexpected behaviour and makes default params far less useful.

It's like whitespace. Everybody has this reaction at first, then they get over it.

Ahem, we have repeatedly intricate issues that are related to this kind of behavior, and I have yet to see an annoying white space bug.

Not to say I think python should be changed on this point. It shouldn't, there are code checkers that warn you on the gotcha, let's use them.

Re: A few things to remember while coding in Python

#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 shouldn't avoid language features just because some people don't know about them. That's as ridiculous as the folks who say "Don't use the ?: operator because folks who haven't taken Intro CS 101 may not be familiar with it." So you spent a couple seconds Googling defaultdict. Great, you now know what a defaultdi…

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 working in C, I'm well aware of how C does bools, but that's because C's values are small and fast, not beautiful and clear. In C, there's barely any abstraction to leak--you just manipulate bits and don't worry about mixing your metaphors. But Python has different priorities, which is why I prefer it to C when my users (and I) won't be hurt by the performance difference.

If we're showing off clarity instead of cleverness, wouldn't this be a better way to demonstrate it:

   return [i/2 for i in nums if i%2 == 0]
And I prefer the concept of "clarity" to "beauty" when it comes to code. Beauty is, well, whatever in the eyes of the beholder. Clarity, for me, is the question of how fast code can be read and understood correctly by a given programmer who is familiar (not more) with the language, not necessarily familiar with other languages, and unfamiliar with what the code does.

The faster such a person can skim the code and understand it correctly, the easier it will be to modify and keep free of bugs. If we're so smart, why don't we show it by using our brains to write code that is quicker to read and understand correctly than code written by lesser lights?

Re: A few things to remember while coding in Python

#65

Earlier quoted context omitted.

It's a mistake. Default values for optional parameters don't act that way in any other language I know of, including Common Lisp, in which functions are also firstclass.

It's most certainly not a mistake; Python 3 would probably have fixed it, if it were. It is an (admittedly, strange) side effect of the way 'def' works.

But 'def' doesn't have to work that way. Consider, in CL:

  > (defvar *fn*
      (let ((x 3))
        (lambda (&optional (y (list nil x)))
          (push 7 (car y))   ; modifies the list
          y)))
  *FN*
  > (funcall *fn*)
  ((7) 3)
  > (funcall *fn*)
  ((7) 3)
From this example you can see two things. First, the binding of 'x' is closed over when the lambda expression is evaluated. And second, the expression that provides the default value of 'y' is evaluated every time the function is called.

There's no fundamental reason it couldn't have worked that way in Python. (I understand that changing the language so it worked that way now would likely break some code.)

EDIT: fixed formatting.

Re: A few things to remember while coding in Python

#66

Earlier quoted context omitted.

It's most certainly not a mistake; Python 3 would probably have fixed it, if it were. It is an (admittedly, strange) side effect of the way 'def' works.

But 'def' doesn't have to work that way. Consider, in CL: > (defvar *fn* (let ((x 3)) (lambda (&optional (y (list nil x))) (push 7 (car y)) ; modifies the list y))) *FN* > (funcall *fn*) ((7) 3) > (funcall *fn*) ((7) 3) From this example you can see two things. First, the binding of 'x' is closed over when the lambda expression is evaluated. And second, the expression that provides the default value of 'y' is evaluat…

Expensive, though.

http://stackoverflow.com/questions/1651154/why-are-default-a...

Re: A few things to remember while coding in Python

#67
post #2

Another handy one I saw recently: varname, = [x for x in l if predicate_with_single_truth_value(x)] The comma after varname is an implicit assert that the list comprehension only contains one element.

A better way: varname = (x for x in l if predicate_with_single_truth_value(x)).next()

That avoids the construction of the list, but doesn't check that the sequence only contains one value, which was the point of the example.

Re: A few things to remember while coding in Python

#68
post #30

Earlier quoted context omitted.

While it seems logical when you understand what's going on, from a practical point of view I can't see how this would ever be useful. The tradeoff appears to be that the functions are first class objects. I'm not sure what the benefit here is though. Does having them as first class objects allow some useful idioms? (I'm a ruby dev but I'm genuinely curious to know what this allows you to do)

It's not designed to be useful, it just is. Functions are objects, yes, and the def statement brings them into being and assigns them to the given name in the current scope: >>> def f(x): ... return x + 5 >>> type(f) >>> dis.dis(f.func_code) 2 0 LOAD_FAST 0 (x) 3 LOAD_CONST 1 (5) 6 BINARY_ADD 7 RETURN_VALUE >>> g = f >>> g(10) 15 >>> g is f True They're just variables in the current scope. If you're quite clever, you…

Thanking you for showing me the 'dis' module. Dis is going to be fun to play with!!

Re: A few things to remember while coding in Python

#70
post #18

Earlier quoted context omitted.

That seems like decidedly unexpected behaviour and makes default params far less useful.

Actually, if you understand the way Python is evaluated (dig in, the core is pretty transparent), it's the only behavior that makes sense in this case. It's also documented as such[1], so it's quite expected. Default parameters are still just as useful for constants, such as: def f(x=0, y="foo", z=3.14159): This, however, is a perfectly Pythonic idiom: def f(L=None): if L is None: L = [] [1]: http://docs.python.org/r…

I am but an egg, but isn't this the same but shorter?

def f(L=None): L = L or []

Post reply on HN