Live data from Hacker News

A few things to remember while coding in Python

satyajit.ranjeev.in

11–20 of 146 posts

Re: A few things to remember while coding in Python

#11

    halve_evens_only = lambda nums: map(lambda i: i/2, filter(lambda i: not i%2, nums))
I still find it rather silly that python doesn't supper a nice list map/filter; it could be so much nicer

    nums.filter(lambda i: i%2 == 0).map(lambda i: i/2)
If they did, even including the annoyingly long-to-type "lambda". List comprehensions are cool and all, but do not really scale visually (i.e. get rather messy) when you have more than one map and filter step.

These arbitrary break-away from OO method style into module+data style (len(L) is another!) are one of the things I hate most about Python. There are some reasons for doing so, but a pure-OO (like Scala) or pure-method+data (like F#) would have saved me many a runtime error.

Re: A few things to remember while coding in Python

#13
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.

Trailing commas are a bit subtle and readers of the code may think it was a mistake. (We spend more time reading code later than writing it in the first place.)

Even Python removed one of its most prominent cases of this, the print command. In Python 2.x you could have a trailing comma after a print to omit the new-line but Python 3's print() function requires print('something', end=' ') to be more explicit about it.

Re: A few things to remember while coding in Python

#14
Generally most use this:

    freqs = {}
    for c in "abracadabra":
        try:
            freqs[c] += 1
        except:
            freqs[c] = 1
If this is really the common idiom, I'd say this is a sign that professional programming has yet to fully mature as a field.

Some may say a better solution would be:

    freqs = {}
    for c in "abracadabra":
        freqs[c] = freqs.get(c, 0) + 1
Okay, so I understood immediately what was going on with the 2nd bit of code.

Rather go for the collection type defaultdict

    from collections import defaultdict
    freqs = defaultdict(int)
    for c in "abracadabra":
        freqs[c] += 1

As a non-pythonista, the 3rd bit of code, I had to Google "defaultdict" to figure out. It's only a couple of seconds to Google, and a professional should know this tidbit, but it seems like premature optimization to me. This brings to mind this post:

http://news.ycombinator.com/item?id=3995185

As a programmer, one's most valuable resource is brainpower. Supposedly, a programmer's most important goal is writing clear code. Look around at what goes on in our industry. There's a lot of our most valuable resource spent on showing off our cleverness, not directed towards the clearest code. To me this is like spending money to show one can spend money or playing an instrument to show off dexterity instead of producing gorgeous sounds.

(I think this starts in school and other environments where one is motivated to show off one's coding chops.)

Most of the complexity in our field accrues like litter: a bit here and a bit there. I think it says something about the culture of the folks who live there.

Re: A few things to remember while coding in Python

#15
post #9

Till now I had never seen Ellipsis. It seems very similar to slice notation [:]. Found an StackOverflow comment [1] that has more details about usage of Ellipsis in slicing higher dimensional array numpy. [1] http://stackoverflow.com/questions/118370/how-do-you-use-the...

Here's a rare example of obfuscated python, deceptively called "Python's Ellipsis Explained": http://blog.brush.co.nz/2009/05/ellipsis/

Re: A few things to remember while coding in Python

#18
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.

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

Re: A few things to remember while coding in Python

#19

Generally most use this: freqs = {} for c in "abracadabra": try: freqs[c] += 1 except: freqs[c] = 1 If this is really the common idiom, I'd say this is a sign that professional programming has yet to fully mature as a field. Some may say a better solution would be: freqs = {} for c in "abracadabra": freqs[c] = freqs.get(c, 0) + 1 Okay, so I understood immediately what was going on with the 2nd bit of code. Rather go…

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 defaultdict is and can use it in your own code. It's useful in a lot of places besides this toy example.

You should avoid gratuitous complexity, where you force the reader to learn something that will never, ever be useful to them again. A great example might be writing your own encryption algorithm, which will be complicated, wrong, under-performant, and totally useless on any other project. If you just use bcrypt (or whatever the recommended best practice is now), then your code works well, and all readers of your code now know about bcrypt and can use it themselves.

Re: A few things to remember while coding in Python

#20
post #11

halve_evens_only = lambda nums: map(lambda i: i/2, filter(lambda i: not i%2, nums)) I still find it rather silly that python doesn't supper a nice list map/filter; it could be so much nicer nums.filter(lambda i: i%2 == 0).map(lambda i: i/2) If they did, even including the annoyingly long-to-type "lambda". List comprehensions are cool and all, but do not really scale visually (i.e. get rather messy) when you have more…

the D language supports that kind of syntax

nums.filter!(i => i%2 == 0).map!(i => i/2);

Post reply on HN