Sets are my #1 favourite Python built-in. I used to have these tedious imperative functions for doing change detection on collections. Then I learned sets and it turned into obvious code like:
added = b - a
removed = a - b
repeated = a & b
Etc.
Of course this is set theory and not Python specific. But still. Learn sets!
Every codebase eventually needs an averaging function, now you don't have to re-implement it yourself every time.
Plus it's a nice toolbox of a few different utilities that you would otherwise need to install numpy/scipy/etc. to get.
I wonder why they didn't have just one median function and control its behaviour with keyword arguments instead of creating 4 different median functions.
I disagree with only one thing in this article. Frozenset is super useful. You should prefer frozenset over set by default imo. Immutable objects are safer to work with, often easier to work with (frozenset is hashable, you can key a dict with it), and sets come up all the time in a lot of work. You can get by with a sorted list, but sets are nicer and faster.
Great point. I do agree that those who use sets heavily should probably know about frozenset. :)
I've never very rarely seen these used in production code though. I'm also not as strongly biased toward them because set objects in my own code are often pretty short-lived so their mutability rarely matters.
> I disagree with only one thing in this article. Frozenset is super useful.
Many of the "don't" callables are useful and I'd say I've used about half (`format` is especially nice as a more flexible version of `str`).
But Python's tendency to mutability and the `set` interface makes frozenset verbose to use & have higher overhead than sets[0]. Usually code is terser and just as clear using sets without mutating them. Which is a shame as of course you lose the safety of enforcing immutability (at runtime but still).
Then again, I guess if you're using a type checker it matters less: it shouldn't let you mutate a `set` if you've typed it as `Set` (rather than `MutableSet`).
[0] IIRC there's only one operation which is specifically optimised for frozensets: copy
I completely agree. Working on complex enterprise Python applications, a pretty significant suite of bugs comes from long-lived, mutable objects. We’ve generally had good luck with preferring immutability wherever possible, both using builtins (tuples rather than lists when possible, frozenset) and custom classes. I just wish frozendict was part of the stdlib!
Ha! That was the thing I was most excited to learn about. I’ve never come across it in any codebases I’ve worked on, but will definitely begin training myself to use it by default over a normal set.
I always tend to recommend intermediate/advanced programmers to take a look at `functools` and `collections` packages - they are filled with amazing things that you haven't even though you need!
My favourites are `functools.partial`, `collections.Counter` and `collections.defaultdict` that are used very often by people who are aware of their existance.
I use defaultdict so damn often, it honestly should even be a builtin in my opinion. You also forgot `itertools`, which imo is even more useful than `functools`. I use `chain` and `groupby` quite often. There's also `collections.deque` which is a quick linked list implementation if you need either a stack or a queue.
Thanks for noting this. I rarely look at my site on mobile and hadn't noticed how big that widget was. I just spent a few minutes making it less visually obtrusive. I may figure out more ways to improve it later.
I notice that "globals" is on the "you won't use this much" pile. I am wondering, when using Python interactively from Emacs, I often do this kind of thing:
if 'myvar' not in globals():
myvar = ...
That way I can just execute the whole buffer instead of having to carefully be picky-choosy about what I send to the interpreter. It's especially helpful if the line involves loading a large file, calculating something that takes a while, or downloading something. Is there a better way to handle this in an interactive context? Like an automatic globals cache of some kind?
(Note, it's helpful to be able to dirty the variable when necessary by simply,
This article covers a lot of good material and I like the breakdown of categories from essential > maybe you'll look this up some day.
My one minor suggestion would be to cover getattr and related methods sooner. I stumbled across that one pretty early on as I was learning programming and it was a serious "Ah ha!" moment. Dynamic lookups with a sensible default value are useful in countless contexts.
It totally depends on the kind of work you're doing. My first few years with Python I never defined a class. I (and imagine most people) were working on code get from a to b. There's a lot of that kind of work to be had. Only later when I started writing modules and libraries did I need to.
I spent many years with Visual Basic before learning Python. Some of the earlier versions of VB were object based, meaning that you could use pre-written objects (standard and third party), but you had to buy a special kit to create your own objects.
This was quite useful for those of us who were bewildered by OOP.
When I learned Python, I was comfortable enough with using objects, that I had no problem creating classes.
So I think it's fair to say that creating classes is something that beginning Python programmers can put off.
Since I introduced Python to my workplace, I get to watch some fairly neophyte programmers develop their skills. These are typically engineers doing scientific programming, not commercial software developers. There's a point where I get to say: "You could put that stuff in a class." And later on, "You're creating too many classes." ;-)
while python is object oriented in the sense that everything is an object it doesn't insist of doing everything via message passing. It's quite happy with basic data types and simple functions (plus decorators and context managers)
I am honestly a bit surprised divmod and complex are so high, I have only used them a couple of times myself - but I think they're almost always mentioned in "Intro to Python" books so most people should at least be familiar with them right?
I’ve been writing Python for a little over a year mostly as glue code and scripting around AWS. I always had a sneaking suspicion that there was more I needed to learn and that I wasn’t doing things the “Pythonic” way.
And that's despite the fact that I read an article a few weeks ago about this new feature! If you haven't read it, I highly recommend it, because there's more to the breakpoint feature than mentioned here (basically, you can set an env variable to choose which callable is activated on breakpoint, meaning you can turn on and off debugging on production systems, or even set prod systems to open a web port for debugging): https://hackernoon.com/python-3-7s-new-builtin-breakpoint-a-...
[+] [-] Waterluvian|6 years ago|reply
added = b - a
removed = a - b
repeated = a & b
Etc.
Of course this is set theory and not Python specific. But still. Learn sets!
[+] [-] ehsankia|6 years ago|reply
[+] [-] joatmon-snoo|6 years ago|reply
[+] [-] MattConfluence|6 years ago|reply
Every codebase eventually needs an averaging function, now you don't have to re-implement it yourself every time. Plus it's a nice toolbox of a few different utilities that you would otherwise need to install numpy/scipy/etc. to get.
[+] [-] lsorber|6 years ago|reply
I wonder why they didn't have just one median function and control its behaviour with keyword arguments instead of creating 4 different median functions.
[+] [-] psalminen|6 years ago|reply
[+] [-] joshuamorton|6 years ago|reply
[+] [-] th|6 years ago|reply
I've never very rarely seen these used in production code though. I'm also not as strongly biased toward them because set objects in my own code are often pretty short-lived so their mutability rarely matters.
[+] [-] masklinn|6 years ago|reply
Many of the "don't" callables are useful and I'd say I've used about half (`format` is especially nice as a more flexible version of `str`).
But Python's tendency to mutability and the `set` interface makes frozenset verbose to use & have higher overhead than sets[0]. Usually code is terser and just as clear using sets without mutating them. Which is a shame as of course you lose the safety of enforcing immutability (at runtime but still).
Then again, I guess if you're using a type checker it matters less: it shouldn't let you mutate a `set` if you've typed it as `Set` (rather than `MutableSet`).
[0] IIRC there's only one operation which is specifically optimised for frozensets: copy
[+] [-] mplanchard|6 years ago|reply
[+] [-] kitotik|6 years ago|reply
[+] [-] hprotagonist|6 years ago|reply
I rewatch it every 6 months or so and usually learn a new trick or two.
[+] [-] JoBrad|6 years ago|reply
[+] [-] kabacha|6 years ago|reply
My favourites are `functools.partial`, `collections.Counter` and `collections.defaultdict` that are used very often by people who are aware of their existance.
[+] [-] ehsankia|6 years ago|reply
[+] [-] abhishekjha|6 years ago|reply
[+] [-] radarsat1|6 years ago|reply
[+] [-] gloflo|6 years ago|reply
[+] [-] th|6 years ago|reply
[+] [-] ASalazarMX|6 years ago|reply
[+] [-] striking|6 years ago|reply
[+] [-] radarsat1|6 years ago|reply
(Note, it's helpful to be able to dirty the variable when necessary by simply,
[+] [-] santiagobasulto|6 years ago|reply
[+] [-] th|6 years ago|reply
[+] [-] rurp|6 years ago|reply
My one minor suggestion would be to cover getattr and related methods sooner. I stumbled across that one pretty early on as I was learning programming and it was a serious "Ah ha!" moment. Dynamic lookups with a sensible default value are useful in countless contexts.
[+] [-] Splendor|6 years ago|reply
Huh. Okay.
[+] [-] pfranz|6 years ago|reply
[+] [-] analog31|6 years ago|reply
This was quite useful for those of us who were bewildered by OOP.
When I learned Python, I was comfortable enough with using objects, that I had no problem creating classes.
So I think it's fair to say that creating classes is something that beginning Python programmers can put off.
Since I introduced Python to my workplace, I get to watch some fairly neophyte programmers develop their skills. These are typically engineers doing scientific programming, not commercial software developers. There's a point where I get to say: "You could put that stuff in a class." And later on, "You're creating too many classes." ;-)
[+] [-] emddudley|6 years ago|reply
[+] [-] civility|6 years ago|reply
[+] [-] jackbrookes|6 years ago|reply
[+] [-] rat87|6 years ago|reply
[+] [-] coldtea|6 years ago|reply
[+] [-] ggm|6 years ago|reply
I used all but one of the MUSTS.
I used a few of the SHOULD
I used a similar few of the MAY
I only used one of the MAYBE-NOT (pow, and I am doing base arithmetic but not crypto)
I don't think I use any of the DONT
I'm interested in moving up on the SHOULD and MAY
[+] [-] ausbah|6 years ago|reply
[+] [-] scarface74|6 years ago|reply
This article confirmed my suspicions. Great post.
[+] [-] chombier|6 years ago|reply
Luckily it's been added only recently (3.7) :)
[+] [-] edanm|6 years ago|reply
And that's despite the fact that I read an article a few weeks ago about this new feature! If you haven't read it, I highly recommend it, because there's more to the breakpoint feature than mentioned here (basically, you can set an env variable to choose which callable is activated on breakpoint, meaning you can turn on and off debugging on production systems, or even set prod systems to open a web port for debugging): https://hackernoon.com/python-3-7s-new-builtin-breakpoint-a-...
[+] [-] amelius|6 years ago|reply
[+] [-] laurentoget|6 years ago|reply
[+] [-] purplezooey|6 years ago|reply
[+] [-] tyingq|6 years ago|reply
[+] [-] mixmastamyk|6 years ago|reply
[+] [-] tigrezno|6 years ago|reply