Python built-ins worth learning(treyhunner.com) |
Python built-ins worth learning(treyhunner.com) |
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'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.
As you do that, you start to realize that you don't need a MutableMapping. Just a Mapping will do, much less a Dict. Same with Set.
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 rewatch it every 6 months or so and usually learn a new trick or two.
To borrow a phrase from Avatar: The Last Airbender, dabeaz is, uh, a mad genius.
My favourites are `functools.partial`, `collections.Counter` and `collections.defaultdict` that are used very often by people who are aware of their existance.
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,
del myvar
)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.
Huh. Okay.
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
This article confirmed my suspicions. Great post.
Luckily it's been added only recently (3.7) :)
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-...
Then I had to write a piece of software that heavily interacted with various bits of physical hardware, each with masses of state (serial communication and so forth). Suddenly the need for isolating state became terribly obvious. After seeing how some libraries did it, I wrote a class for every bit of hardware that abstracted the state away and provided a functional interface. It all worked terribly well, and it was a real lightbulb moment for me.
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." ;-)
> The Python Datamodel: When and how to write objects - https://www.youtube.com/watch?v=iGfggZqXmB0
Linked lists are slow at accessing data in the middle, but you can very quickly add and remove stuff from the ends, hence double-ended queue. A stack is basically a deque where you only use the tip, so deque is very versatile like that.
Oh, and of course there's not one, but half a dozen power supplies. You could pass around the blobs of state seperately of course, but now you have to manage their scope independently from the functions that operate on them - a useless decoupling that adds overhead. What I ended up with was something like:
[psu.enable() for psu in psus]
Which you can always do, whenever psus is within scope. Hard to get terser and more idiomatic than that.
I know this because I wanted to do the same thing and have looked all over for a justification for it. In this case most people seem to agree that the bog standard for loop is the way to go:
for psu in psus:
psu.enable()
Some people (my boss) will even put it on a single line, so you don't lose much terseness.I think the rule of thumb is don't use a list comprehension unless you're going to use the list afterwards, else you're wasting an allocation.
To be sure classes have a place and can be really useful, but so many people just create classes when they add no benefits.
Clear code always wins imho
I think the reason I instinctively write it this way is because in my mind, I basically think of list comprehensions as sugar for map + lambda. I'm "really" trying to write map(enable, psus). But of course, it's a method, so you need the instance[2] - map(lambda psu: psu.enable(), psus). The reason I prefer a map over a for loop is because it's a habit borne of the principle of least power - map provides a guarantee than no "funny business" (data dependency) is going on between the elements of the list you're iterating over. I scrupulously avoid for loops on principle, unless I need that kind of funny business. Of course in this case the for loop is so short as to make no difference, but like I say - it's a habit. In my code, "for" means "funny business here".
[1] not that it matters in this case - you're not toggling power supplies in a tight loop.
[2] Technically, in Python, map(psus[0].enable, psus) would work if psus was not empty. Or you could spawn a new instance: map(PSU().enable, psus). But ugh, talk about defeating the purpose.