Live data from Hacker News

A Python Guide for the Ages

gto76.github.io

31–40 of 59 posts

Re: A Python Guide for the Ages

#31

I'm surprised to see mutable default values not mentioned. It's bitten me more than once to discover that: def f(xs = []): xs.append(5) return xs print(f()) print(f()) will print: [5] [5,5] and I love python despite this horrendous decision, but it should be mentioned more often in beginner resources. edit: thanks for the downvote? I've answered on the order of dozens of questions about this very mechanic on SO, via…

Don't let it get to you. If you're critical of something, someone will always downvote.

On the other hand this behavior means that the default value will only get computed once, so I guess Guido thought it's useful if that value comes e.g. from an expensive function.

On the other other hand you could achieve that latter behavior with a lazy function even if the arguments were reevaluated every time you call the function.

What do others like Common Lisp and Ruby do here?

Re: A Python Guide for the Ages

#32
I'm missing type annotations but I think it's aa cool cheat sheet.

These thing are useful for me who uses python every couple of months. Not often enough to remember it, so I need some reference to refresh my memory.

Re: A Python Guide for the Ages

#33
post #9

Earlier quoted context omitted.

It’s consistent with try…else and if…else so I actually think it’s ok.

"else" usually means "instead of" or "otherwise" in those patterns. If the original case doesn't run, then the else case runs instead. In a for loop, the else clause only runs if the loop successfully completes (isn't broken), so the else in for-else means the total opposite of what it means in every other pattern. I think it would make a lot more sense if it were replaced with "done" or "upon" or something else that…

You could read it as "either process all of these elements, or otherwise do this other thing". If we break, we're not processing all of the elements (the normal case), so we do the "else" part instead.

Edit: This is wrong. See replies.

Re: A Python Guide for the Ages

#34

There are a couple of language features in Python that I thought were cool when I discovered them, but actually have never ever find a need for them in my code. The first is using an "else" clause in a "for" loop, and the second is returning a value from a generator. Curious whether anybody actually uses either of those.

for/else is actually super useful for searching through a sequence or for iterating with a possible failure. Something like, for i in range(n): if search(i) == val: break else: raise KeyError("not found") found_index = i It reduces the need for an additional flag. More importantly it makes it easier to ensure that the break condition is satisfied such that the loop variable can be used properly later on. Personally,…

What's the advantage over the following?:

  for i in range(n):
      if search(i) == val:
          break
      raise KeyError("not found")
  found_index = i

Re: A Python Guide for the Ages

#35

I'm surprised to see mutable default values not mentioned. It's bitten me more than once to discover that: def f(xs = []): xs.append(5) return xs print(f()) print(f()) will print: [5] [5,5] and I love python despite this horrendous decision, but it should be mentioned more often in beginner resources. edit: thanks for the downvote? I've answered on the order of dozens of questions about this very mechanic on SO, via…

Default values for keywords are saved as part of the function signature itself, at function definition time.

Without this it’s not clear how you’d introspect the default kwarg values of a function? Would they be computed every time the function is inspected? If they are lazy then what if the default value is expensive to compute or has side effects?

So I would not say it’s a horrendous decision, it’s a clear trade off that IMO fits quite well in the Python ethos - everything is an object, and everything can be introspected.

Re: A Python Guide for the Ages

#36

Earlier quoted context omitted.

for/else is actually super useful for searching through a sequence or for iterating with a possible failure. Something like, for i in range(n): if search(i) == val: break else: raise KeyError("not found") found_index = i It reduces the need for an additional flag. More importantly it makes it easier to ensure that the break condition is satisfied such that the loop variable can be used properly later on. Personally,…

What's the advantage over the following?: for i in range(n): if search(i) == val: break raise KeyError("not found") found_index = i

I think this snippet would raise a KeyError whenever the index you're searching for is greater than 0.

Re: A Python Guide for the Ages

#37
post #33
post #9

Earlier quoted context omitted.

"else" usually means "instead of" or "otherwise" in those patterns. If the original case doesn't run, then the else case runs instead. In a for loop, the else clause only runs if the loop successfully completes (isn't broken), so the else in for-else means the total opposite of what it means in every other pattern. I think it would make a lot more sense if it were replaced with "done" or "upon" or something else that…

You could read it as "either process all of these elements, or otherwise do this other thing". If we break, we're not processing all of the elements (the normal case), so we do the "else" part instead. Edit: This is wrong. See replies.

That would make total sense if it were correct. That's exactly how I think most people would intuit it

However, that's exactly how it doesn't work and that's my point. The else clause is only ran if the loop DOESN'T break.

Re: A Python Guide for the Ages

#39
post #37
post #33

Earlier quoted context omitted.

You could read it as "either process all of these elements, or otherwise do this other thing". If we break, we're not processing all of the elements (the normal case), so we do the "else" part instead. Edit: This is wrong. See replies.

That would make total sense if it were correct. That's exactly how I think most people would intuit it However, that's exactly how it doesn't work and that's my point. The else clause is only ran if the loop DOESN'T break.

Hmm! Yes, you're right. Even though I knew exactly how it works and I sometimes use it, I still got confused, so maybe it is a confusing feature after all. :)

Re: A Python Guide for the Ages

#40

Earlier quoted context omitted.

for/else is actually super useful for searching through a sequence or for iterating with a possible failure. Something like, for i in range(n): if search(i) == val: break else: raise KeyError("not found") found_index = i It reduces the need for an additional flag. More importantly it makes it easier to ensure that the break condition is satisfied such that the loop variable can be used properly later on. Personally,…

What's the advantage over the following?: for i in range(n): if search(i) == val: break raise KeyError("not found") found_index = i

That version doesn't work. It raises KeyError on the first iteration if the if statement is false.

The point of the for / else is that the else only gets evaluated when the for terminates without a break. So in the example you only get a KeyError if the search() never returns val.

Part of the confusion I guess is that the else: in my example is paired with for, not with if, Python indentation being significant etc.

Post reply on HN