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.
Walrus operator. I don't think I've seen it in the wild either. Perhaps too new?
A Python Guide for the Ages
51–59 of 59 posts
Re: A Python Guide for the Ages
#52Re: A Python Guide for the Ages
#53The best cheatsheet which I have ever seen (besides maybe cheats.rs) is this Python cheatsheet by Laurent Pointal, absolutely outstanding in many ways: https://perso.limsi.fr/pointal/_media/python:cours:mementopy...
It's good, although doesn't mention f-strings, which makes string manipulation in python next-level.
Re: A Python Guide for the Ages
#54I'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…
Re: A Python Guide for the Ages
#55Earlier quoted context omitted.
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.
Re: A Python Guide for the Ages
#56Earlier quoted context omitted.
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.
Before being introduced to `for`/`else`, I'd have written the example you gave as:
result = None
for i in range(n):
if search(i) == val:
result = i
if not result:
raise KeyError("not found")Re: A Python Guide for the Ages
#57Earlier 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…
Re: A Python Guide for the Ages
#58Earlier quoted context omitted.
I find generators useful when working with very large data structures because generators can be pretty efficient. You can also use them to write little helper functions. Have a look at this package and its source [0]. Oh, and don't feel bad if you never have a need for generators! For the longest time I felt like a steal for rarely using classes but I am over it now :) 0. https://more-itertools.readthedocs.io/en/stab…
They didn't say they hadn't used generators at all. They said they hadn't made use of "returning a value from a generator" which is different from the usual method of yielding from them. def my_generator(): yield 1 yield 2 return 3 If you use that generator in a for loop then it will only put 1 and 2 into the iterator variable. You have to use the generator in a more direct way to get access to the 3. I haven't made…
def lex(src):
state = skip_whitespace
while state is not None:
state = yield from state()
It wasn't particularly essential to use the return value from the generator here, as I could have just made the state variable available in the scope of the state functions for them to mutate, but this seemed like a cleaner way to do it as it enforced the idea that each new state corresponded to a new function.Re: A Python Guide for the Ages
#59There 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.
I've used both, for with else more often. It avoided some booleans and if's that would have been much less clear/easy to get wrong. I'd like a different name for for "for's" else. I've been using method/function redefinition in place of conditionals related to initialization.
Inside any loop are a conditional and a jump. In pseudocode:
if not then
else //loop is done
If we 'break' in the body of the loop for some reason, we will never hit the 'else' in this chunk of code. As Mr. Hettinger explains, this is obvious to anyone reading Knuth or coming from a 'goto' style of control flow. This is not an insult, but an observation. (Un)Fortunately, structured programming is the absolute norm now, and we learn looping constructs directly, rather than learning 'goto' and then building to looping constructs. Especially in a language with rich iteration protocols, such as Python, it is very much unapparent that the looping constructs are fancy wrappers around 'goto'.Link to the talk: https://youtu.be/OSGv2VnC0go?t=948