The author has a second edition out with 90 examples at <a href="https://effectivepython.com/" rel="nofollow">https://effectivepython.com/</a>, and the corresponding github repo at <a href="https://github.com/bslatkin/effectivepython" rel="nofollow">https://github.com/bslatkin/effectivepython</a><p>Its been updated to be exclusive to 3.x, including 3.8 samples.
On “return generators instead of lists” I think it’s also important when you do this to return use a context manager to manage the generators lifetime. Otherwise you might be surprised when the underlying file or source is closed later in your code.<p>I blogged about this:
<a href="https://opensourceconnections.com/blog/2020/06/10/python-generators-and-context-managers/" rel="nofollow">https://opensourceconnections.com/blog/2020/06/10/python-gen...</a>
Great suggestions for general-purpose code, but I would NOT recommend following them in 'mathematically dense' code (e.g., deep learning models), for which being able to fit as much logic as possible into a single editing screen becomes increasingly important as we increase the complexity of the code.<p>Taken to the extreme, the "fit as much logic as possible into a single screen" approach leads naturally to code that looks a lot like something written in APL or one its descendants (J, K, etc.). I recognize this is not for everyone.<p>Personally, I think Jeremy Howard and the folks at fast.ai have struck a pretty good balance of readability and succinctness with their coding style for ML/AI code:<p><a href="https://docs.fast.ai/dev/style.html" rel="nofollow">https://docs.fast.ai/dev/style.html</a>
> Assigning to a list slice will replace that range in the original sequence with what's referenced even if their lengths are different.<p>Not only that, but you can assign to a slice with a stride:<p><pre><code> In [1]: r = list(range(10))
In [2]: r
Out[2]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [3]: r[1::3] = 10, 20, 30
In [4]: r
Out[4]: [0, 10, 2, 3, 20, 5, 6, 30, 8, 9]</code></pre>
Items 7 and 8 seem to be at odds with each other to me, don't use reduce and map because it's ugly and unreadable, but if you use the alternative for reduce and map then you can't make a deeper pipe because it becomes too complicated to read? Get real!<p>Is it even true that comprehensions are faster than reduce and map? I write a lot of python with reduce and map, and I know it's not considered a best practice for perf reasons, but whenever I go-ahead and rewrite it in the "more pythonic" way, I can't help but think that it ends up a lot less readable. I feel like this divide makes functional programming in python more of a hassle than it should be.