7 ms·
A Python Guide for the Ages
- runjake 5y agoI like this. For those of you for whom this list is too terse, check out the excellent LearnXinYminutes site at https://learnxinyminutes.com/docs/python/ https://learnxinyminutes.com/docs/python/
- mellosouls 5y agoGreat site. Discussed the other day here: https://news.ycombinator.com/item?id=29518955 https://news.ycombinator.com/item?id=29518955
- mellosouls 5y agoTo the downvoter(s): yeah I know we shouldn't comment on them, but you made me smile at the gesture today, take it steady. Merry Xmas!
- framecowbird 5y agoThere 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.
- 63 5y agoI actually saw someone use that for-else pattern in advent of code earlier this month. I believe the consensus was that it was definitely the perfect choice for the given use case, but neither he nor I would ever dare use it in production because nobody knows about it and it's super unintuitive. I think the idea is cool (albeit rarely useful), but a different word than "else" for the same functionality would go a long way.
- nneonneo 5y agoI used it a bunch in Advent of Code as well. It’s very useful for “search” loops, which should break on finding the target, or do something else if it isn’t found. Generator return, on the other hand, is something I didn’t even know about (basically, return X in a generator raises StopIteration(X)). I don’t think it’s super useful because even inspecting the arguments to an exception tends to be uncommon practice in most code I’ve seen (more frequently, you just want to report or suppress the error depending on its type). I’m sure there’s a niche use for it somewhere though!
- globular-toast 5y agoInstead of avoiding it in production code, it's better to understand that it's the perfect place for a comment. For example: for ...: ... else: # loop ended, no positions found return ...
- mixmastamyk 5y agoUse with a short comment: for … : … else: # break didn’t occur … I typically make it even shorter, but this is probably the most readable.
- anamax 5y agoI'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.
- AlphaSite 5y agoIt’s consistent with try…else and if…else so I actually think it’s ok.
- 63 5y ago"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 communicates how it works.
- jermy 5y agoThe way you describe is how it worked in zope templates (allowing a 'no items here' text if there was nothing to iterate over in a list) - it was frustrating that the later python implementation was different.
- ptx 5y agoYou 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.
- 63 5y agoThat 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.
- tjpnz 5y agoI prefer using the else clause to maintaining an "is_found" flag. Although this is lesser known syntax so I probably wouldn't use it when multiple developers are involved.
- nneonneo 5y agoYeah, the biggest risk with for-else is that some inexperienced dev comes along and misreads the else as belonging to an if statement inside the for (or, worse, attempting to “fix” it). I’ve seen this happen more than once…
- xmcqdpt2 5y agoYes I always comment on it for this reason, sometimes (if I know the code will be maintained by someone with less python experience) with a link to the standard doc. It's actually a super useful pattern for any kind of search iteration. I've used it many times.
- dr_kiszonka 5y agoI 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/stable/ https://more-itertools.readthedocs.io/en/stable/
- quietbritishjim 5y agoThey 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 use of return values from generators in my code either, but I believe they're used under the hood in coroutines in async code.
- housecarpenter 5y agoI used generators with return values once when writing a lexer. I had generators for each of a bunch of different states of the lexer (e.g. skipping over whitespace, reading a numeric literal, reading a string literal, etc.). Each generator would yielded the tokens that it could and then either return one of the other generators (if a state transition was required) or None (if it reached the end of the input and the state was one where this wasn't an error condition). The whole thing was tied together with this function: 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.
- globular-toast 5y agofor/else is unfortunately named (although makes sense if you think about the hidden if/else in a loop). It is essentially use to distinguish between "this loop ended naturally" (the else condition) or "this loop was broken". I used it recently in some mutating code in which I wanted to make a change, and also know if it did actually make a change. If the routine gets to the end of the loop without finding a place to make a change, it hits the "else" and returns False.
- xmcqdpt2 5y agofor/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, I think an else condition should almost always be there for loops that gets broken early, similarly to always finishing if else chain with a final else. ETA: Another pattern where it's really useful is to replace while True: with a safer guaranteed terminating loop, for i in range(MAX_ITER): ... else: raise RuntimeError("exceeded max iterations")
- montebicyclelo 5y agoWhat's the advantage over the following?: for i in range(n): if search(i) == val: break raise KeyError("not found") found_index = i
- Arrrlex 5y agoI think this snippet would raise a KeyError whenever the index you're searching for is greater than 0.
- xmcqdpt2 5y agoThat 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.
- deleted 5y ago[deleted]
- montebicyclelo 5y ago
- CodeGlitch 5y agoWalrus operator. I don't think I've seen it in the wild either. Perhaps too new?
- mixmastamyk 5y agoIt’s used a lot in simple situations. However never seen it used for multiple values, which was the reason given for using := instead of the “as” keyword used elsewhere. So I cringe every time I use it.
- asicsp 5y agoPrevious substantial discussion: https://news.ycombinator.com/item?id=19075325 https://news.ycombinator.com/item?id=19075325 (Feb 4, 2019 | 81 comments) Other cheatsheets (excluding learnxinyminutes already mentioned in another comment) * Python Crash Course: https://ehmatthes.github.io/pcc_2e/cheat_sheets/cheat_sheets/ https://ehmatthes.github.io/pcc_2e/cheat_sheets/cheat_sheets... * Scientific Python: https://ipgp.github.io/scientific_python_cheat_sheet/ https://ipgp.github.io/scientific_python_cheat_sheet/
- ruph123 5y agoThe 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:mementopython3-english.pdf https://perso.limsi.fr/pointal/_media/python:cours:mementopy...
- bobnamob 5y agoAdding to the list, this clojure cheat sheet is always a good resource: https://clojure.org/api/cheatsheet https://clojure.org/api/cheatsheet
- CodeGlitch 5y agoIt's good, although doesn't mention f-strings, which makes string manipulation in python next-level.
- ruph123 5y agoYeah, unfortunately it hasn't been updated in a few years. Real bummer.
- darkbatman 5y agoDoes someone know similar guide for javascript/node.js or its a good thing to start one?
- asicsp 5y agohttps://learnxinyminutes.com/docs/javascript/ https://learnxinyminutes.com/docs/javascript/ might help (there's further reading links at the end as well)
- abhishekjha 5y agoI love that it is easily printable from the browser, just CTRL+P.
- tux 5y agoVery nice detailed cheatsheet thank you! Every programming language should have similar cheatsheet.
- phoenix24 5y agodoes anyone have recommendations for a good ruby cheatsheet?
- asicsp 5y agoThese might help: * https://learnxinyminutes.com/docs/ruby/ https://learnxinyminutes.com/docs/ruby/ * https://github.com/ThibaultJanBeyer/cheatsheets/blob/master/Ruby-Cheatsheet.md https://github.com/ThibaultJanBeyer/cheatsheets/blob/master/... * https://github.com/lifeparticle/Ruby-Cheatsheet https://github.com/lifeparticle/Ruby-Cheatsheet
- gorgoiler 5y agoIntegral?
- adenozine 5y agoI'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 IRC, and more... it's a well-known confusing factor
- kubb 5y agoDon'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?
- jinwoo68 5y agoIn Common Lisp, default values of optional parameters are evaluated each time (only when the argument is not given of course). They can even reference other arguments that come earlier.
- orf 5y agoDefault 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.
- maple3142 5y agoIt might be confusing as it is different from some other languages, such as C++ and JavaScript. They both evaluate default parameter when the function are called.
- kubb 5y agoI'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.
- mark_l_watson 5y agoThanks for whoever did this, a nice resource! I have been forced to use Python for many years because I am mostly payed to do deep learning. I really enjoyed carefully reading through this. Good job.
- hereforphone 5y ago"For the ages". Or at least until they release Python 4
- hnarn 5y agoI’ve seen it said multiple times that it’s very likely that there will not be a Python 4. https://www.techrepublic.com/article/programming-languages-why-python-4-0-will-probably-never-arrive-according-to-its-creator/ https://www.techrepublic.com/article/programming-languages-w...
- hereforphone 5y agoThat was a joke about Python 3.