Live data from Hacker News

A few things to remember while coding in Python

satyajit.ranjeev.in

21–30 of 146 posts

Re: A few things to remember while coding in Python

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

Re: A few things to remember while coding in Python

#22
post #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.

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/reference/compound_stmts.html#functio...

Re: A few things to remember while coding in Python

#23
post #3

My only complaint with this list is conditional assignments. They make it harder for me to understand the code. I am used to the if being at the start and when it isn't it takes more time for me to parse what the real meaning of the line is.

One of the reasons Python stopped being my favorite programming language was the appearance of what seemed to me to be Perl envy. I hadn't seen conditional assignments before, but they don't exactly make me regret that choice.

Re: A few things to remember while coding in Python

#24
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…

Python offers filtering expressions in its generator syntax. I find Python's "lambda" hurts readability for most uses, which pains me as a Lisp geek. Your example, as a generator:

    halve_evens_only = (i / 2) for i in nums if (i%2 == 0)
The parens aren't necessary, but they help readability for people who aren't used to the generator order of operations. (Again, Lisp geek, more parens means more readable in my fractured mind.)

Re: A few things to remember while coding in Python

#25
post #12

Generally, most use this: freqs = {} for c in "abracadabra": try: freqs[c] += 1 except: freqs[c] = 1 Who does this?!

Immature programmers. It's analogous to musicians who play everything as fast and ornately as possible.

Beat me to my equivalent answer: "java programmers."

Re: A few things to remember while coding in Python

#26

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…

Or just say:

    from collections import Counter
    freqs = Counter("abracadabra")
I was surprised to see that missing, given that Counter was mentioned in the next section.

Re: A few things to remember while coding in Python

#27
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…

Or just embrace the tao of the tuple:

    def f(L=()):
        ...

Re: A few things to remember while coding in Python

#28

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…

I agree with the spirit of your argument.

In fact, I almost came here to write a parallel comment: I'm really not sure that reversing the list 'a' with 'a[::-1]' is better than 'reversed(a)', which usually effectively does the same thing, but whose meaning is much more obvious.

But, while I agree with your general point, in the specific case of 'defaultdict', I differ.

I use 'defaultdict' all the time and I'm glad its there. It feels cleaner than 'freqs.get(c,0)'. I define the default value in one place, and then the interface to my datastructure is simpler; hence as I continue writing, I can spend more of my brainpower in the problem domain.

Its a small detail, but its one less thing to think about when writing a complex algorithm.

Re: A few things to remember while coding in Python

#29
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…

[deleted]

Re: A few things to remember while coding in Python

#30
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…

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)
Post reply on HN