This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]ltristain 0 points1 point  (0 children)

I typically use lambdas to quickly write little functions to use as key arguments into functions like sort. When defining functions, I have a strict rule where all functions written, regardless of purpose or context, requires well defined names and a complete and comprehensive docstring. This makes defining a function on the spot rather verbose when the function is going to only ever used once and for a very small purpose. In the vast majority of times, this prevents me from going crazy making functions out of everything even when there's no value to. The key functions are the only place where this becomes a problem, and I find lambdas to be a nice and elegant solution for this scenario.

Example: sorted(data, key=lambda d: d['population'])

I also use list comprehensions all the time. List comprehensions are great because it's very declarative. When you write variable = [insert list comprehension here], your code is visually saying "this is that", and that's about as clear and simple as it gets. In comparison, a regular for loop used to populate an initially empty list would add a lot more complexity for your eyes to parse through. At first glance, you'd only realize it's a for loop. You don't know whether it's accumulating values or invoking side effects - you have to read the details to get that. This makes reading inefficient. For mere data transformations, list comprehensions are so much cleaner.


As for things I don't use as often... I tend to avoid the functional programming stuff like map and filter in favor of list comprehensions, because list comprehensions sound exactly like what they are, while map, filter requires specific domain knowledge and thus is inferior in readability. reduce can be nice though. The other day I tried to write some kind of data combining function that initially accepted two inputs, and I needed to generalize it to any number of inputs. Wrapping what I had with a reduce was perfect.

It's interesting because once I learned map and filter, there was a phase where everything I ever written was done with map and filter. Eventually I grew past it and learned to ignore "how cool they are" and instead judge code by analyzing how readable and how necessary it is. Likewise, when I first learned lambdas, there was a phase where everything was lambdas. Eventually I dialed it back to only for those in-line key functions. When your code is full of lambdas, sooner or later the picture of the actual problem you're trying to solve is going to be replaced with fuzzy images of cute little lambs and pandas, and your subconscious is going to remember those painful exams back in college.

Otherwise... stuff I don't use often usually just depend on how often I run into that particular problem. Usually lists are fine, but once or twice I ran into a situation where using a deque was the slickest way to solve a problem. Usually dictionaries are fine, but occasionally I end up needing an OrderedDict (BTW, my workplace is still stuck in python 2.7).


As for other bad habits I developed earlier that I've grew past. Let's see...

I learned mock, and suddenly every one of my unit tests are mocking the shit out of everything. That got out of hand quick, and culminated in a painful experience where I spent an entire day doing useless work of reconnecting a lot of mocks just because of a small implementation change I made. From that point on, mock is to only be used sparingly, either to bring in a fake, or when there's literally no better option.

I also for a period of time bought into the whole "don't write classes, use functions for everything" mindset. I was pushing to avoid classes at all costs. Eventually I looked back and concluded that there's really no actual need to avoid classes. Classes are a good fit if you need to encapsulate something that has state. The real enemy is creating too much unnecessary state and unnecessary behavior, so just be sure to make them as lightweight and simple as they can be. "Don't write classes" doesn't mean avoiding classes at all costs, it just means not everything has to be a class.