30 Python Language Tricks That Will Make You a Better Coder

If you think you mastered the language, you’ve got to read this

Image by author

There are lots of little tricks that can make life easier for a Python coder. Some of these will be known to you, but I’m sure there are at least a couple that you haven’t seen before.

If you’re done reading, also take a look at our latest article on concurrency:

1. The Python Ellipsis

The Python ellipsis is a sequence of three dots. It’s used a lot in conventional (non-programming) languages. But what you might not know, is that it’s a valid object in Python too:

>>> ...
Ellipsis

Its primary use seems to be in matrix slicing operations in NumPy. However, you can use it as a placeholder in a function that you haven’t implemented yet, instead of using pass, as most people do:

def my_awesome_func():
...

This is valid Python code, and it doesn’t look too bad now, does it?

2. Data classes

Since version 3.7, Python offers data classes. There are several advantages over regular classes or other alternatives like returning multiple values or dictionaries:

  • a data class requires a minimal amount of code
  • you can compare data classes because __eq__ is implemented for you
  • you can easily print a data class for debugging because __repr__ is implemented as well
  • data classes require type hints, reduced the chances of bugs

Here’s an example of a data class at work:

3. The Zen of Python

One of the earliest Python pep’s is PEP-20. It’s a list of 19 theses relating to Python programming called ‘The Zen of Python.’ These rules date back to 2004 and are in turn based on PEP-8.

A little Easter egg that has been present in Python for a long time lists these 19 rules:

So as long as you have a Python REPL, you can get these rules on your screen!

4. Anonymous functions

Sometimes, naming a function is not worth the trouble. For example when you’re sure the function will only be used once. For such cases, Python offers us anonymous functions, also called lambda functions.

‘Anonymous’ — Photo by Tarik Haiga on Unsplash

A lambda function can be assigned to a variable, creating a concise way of defining a function:

>>> add_one = lambda x: x + 1
>>> add_one(3)
4

It gets more interesting when you need to use a function as an argument. In such cases, the function is often used only once. As you may know, map applies a function to all elements of an iterable object. We can use a lambda when calling map:

>>> numbers = [1, 2, 3, 4]
>>> times_two = map(lambda x: x * 2, numbers)
>>> list(times_two)
[2, 4, 6, 8]
>>>

In fact, this is a pattern that you’ll see often. When you need to apply a relatively simple operation on each element of an iterable object, using map() in combination with a lambda function is concise and efficient.

5. List Comprehensions

A list comprehension can replace ugly for loops used to fill a list. The basic syntax for a list comprehension is:

[ expression for item in list if conditional ]

A very basic example to fill a list with a sequence of numbers:

And because you can use an expression, you can also do some math:

Or even call an external function:

And finally, you can use the ‘if’ to filter the list. In this case, we only keep the values that are dividable by 2:

6. In place variable swapping

A neat little trick that can save a few lines of code:

7. Named String Formatting

I don’t see many people using this. I must admit that I love f-strings, and have used them from the day they became available. But if my data is already in a dictionary, I use this named string formatting trick instead:

You can even (ab)use the locals() function here, but with modern Python versions you should really turn to f-strings instead:

8. Nested list comprehensions

Remember the basic syntax of a list comprehensions? It’s:

[ expression for item in list if conditional ]

If expression can be any valid Python expression, it can also be another list comprehension. This can be useful when you want to create a matrix:

>>> [[j for j in range(3)] for i in range(4)]
[[0, 1, 2], [0, 1, 2], [0, 1, 2], [0, 1, 2]]

Or, if you want to flatten the previous matrix:

>>> [value
for sublist in m
for value in sublist]
[0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2]

The first part loops over the matrix m. The second part loops over the elements in each vector.

9. Required Keyword Arguments

You can force keyword arguments. To do so, use an asterisk before the arguments you want to force as keyword arguments. Or, as shown below, before everything, forcing all argument to be keyword arguments:

>>> def f(*, a, b):
... print(a, b)
...
>>> f(1, 2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: f() takes 0 positional
arguments but 2 were given
>>> f(a=1, b=2)
1 2
>>>

10. Use The Underscore in The REPL

You can obtain the result of the last expression in a Python REPL with the underscore operator, e.g. in the Python REPL this looks like:

>>> 3 * 3
9
>>> _ + 3
12

This works in the IPython shell too.

11. Check for a minimum required Python version

You can check for the Python version in your code, to make sure your users are not running your script with an incompatible version. Use this simple check:

12. Decorate your functions

Decorators are wrappers around a function that modify the behavior of the function in a certain way. There are many use-cases for decorators, and you may have used them before when working with frameworks like Flask.

Let’s create our own decorator; it’s simpler than you might expect and might come in handy someday:

def print_argument(func):
def wrapper(the_number):
print("Argument for",
func.__name__,
"is", the_number)
return func(the_number)
return wrapper
@print_argument
def add_one(x):
return x + 1
print(add_one(1))

Inside print_argument, we define a wrapper function. This function prints the argument and the name of the called function. Next, it executes the actual function and returns its result as if the function was called regularly.

With @print_argument we apply our decorator to a function. Perhaps unnecessary to say: this decorator can be re-used for other functions too.

The output of our little script will be:

Argument for add_one is 1
2

13. Return multiple values

Functions in Python can return more than one variable without the need for a dictionary, a list or a class. It works like this:

What we are actually doing here, is returning a tuple. We could have written return (name, birthdate) as well, with the same effect. And if you’re wondering whether you can return more than two values this way: yes you can!

This is alright for a limited number of return values. But anything past 3 values should be put into a (data) class.

14. Merging dictionaries

Since Python 3.5, it became easier to merge dictionaries. And with Python 3.9, even more so!

If there are overlapping keys, the keys from the first dictionary will be overwritten.

15. Slicing a list

The basic syntax of list slicing is:

a[start:stop:step]

Start, stop and step are optional. If you don’t fill them in, they will default to:

  • 0 for start
  • the end of the list for stop
  • 1 for step

Here are some examples:

16. Check memory usage of your objects

With sys.getsizeof() you can check the memory usage of an object:

Woah… wait… why is this huge list only 48 bytes?

It’s because the range function returns a class that only behaves like a list. A range is a lot more memory efficient than using an actual list of numbers.

You can see for yourself by using a list comprehension to create an actual list of numbers from the same range:

17. Using * and ** for Function Argument Unpacking

Some functions require a long list of arguments. Although this should be avoided altogether (e.g. by using data classes), it’s not always up to you. In such cases, the second-best option is to create a dictionary with all the named arguments and pass that to the function instead. It will generally make your code more readable.

You can unpack a dictionary for use with named keywords by using the ** prefix:

Similarly, we can use a single * to unpack an array and feed its content as positional arguments to a function:

18. String to title case

This is just one of those lovely gems. If you want to quickly get a nice looking headline, use the title method on a string:

It’s not perfect though. You can implement a better version with a regex, as explained in this article.

19. Split a string into a list

You can split a string into a list of strings. In this case, we split on the space character:

To split on whitespace, you actually don’t have to give split any arguments. By default, all runs of consecutive whitespace are regarded as a single whitespace separator by split. So we could just as well use mystring.split().

Split also allows a second parameter, called maxsplit, which defines the maximum number of splits. It defaults to -1 (no limit). An example where we limit the split to 1:

>>> mystring.split(' ', 1)
['The', 'quick brown fox']

20. Create a string from a list of strings

And vice versa from the previous trick, create a string from a list and put a space character between each word:

If you were wondering why it’s not mylist.join(" ") — good question!

It comes down to the fact that the String.join() function can join not just lists, but any iterable. Putting it inside String prevents implementing the same functionality in multiple places.

21. Query JSON

JMESPath is a query language for JSON, which allows you to obtain the data you need from a JSON document or dictionary easily. This library is available for Python, but also for many other programming languages, meaning that if you master the JMESPath query language, you can use it in many places.

Here’s some example code to get a feeling for what’s possible:

>>> import jmespath
>>> persons = {
... "persons": [
... { "name": "erik", "age": 38 },
... { "name": "john", "age": 45 },
... { "name": "rob", "age": 14 }
... ]
... }
>>> jmespath.search('persons[*].age', persons)
[38, 45, 14]

Follow the link to learn more about JMESPath for Python.

22. Reversing strings and lists

You can use the slice notation from above to reverse a string or list. By using a negative stepping value of -1, the elements are reversed:

23. Get unique elements from a list or string

By creating a set with the set() function, you get all the unique elements from a list or list-like object:

24. Valid Dictionary Values

You can put anything in a dictionary. You’re not limited to numbers or strings. In fact, you can put dictionaries and lists inside your dictionary and access the nested values in a very natural way:

>>> a = { 'sub_dict': { 'b': True }, 'mylist': [100, 200, 300] }
>>> a['sub_dict']['b']
True
>>> a['mylist'][0]
100

Python’s JSON decoding and encoding library uses this feature of Python when parsing more complex JSON documents. It creates nested trees of lists, dictionaries, and other valid data types.

Read all about dictionaries in this article:

25. Ternary Operator For Conditional Assignment

This is another one of those ways to make your code more concise while still keeping it readable:

[on_true] if [expression] else [on_false]

As an example:

x = "Success!" if (y == 2) else "Failed!"

26. Counting occurrences in a list

You can use Counter from the collections library to get a dictionary with counts of all the unique elements in a list:

27. Chaining comparison operators

Create more readable and concise code by chaining comparison operators:

28. Working with dates

Photo by Ocean Ng on Unsplash

The python-dateutil module provides powerful extensions to the standard datetime module. Install it with:

pip3 install python-dateutil

You can do so much cool stuff with this library. I’ll limit the examples to just this one that I found particularly useful: fuzzy parsing of dates from log files and such.

Just remember: where the regular Python datetime functionality ends, python-dateutil comes in!

29. Using map()

One of Python’s built-in functions is called map(). The syntax for map() is:

map(function, something_iterable)

So you give it a function to execute, and something to execute on. This can be anything that’s iterable. In the examples below I’ll use a list.

Take a look at your own code and see if you can use map() instead of a loop somewhere! You may have noticed, that list comprehensions do exactly the same thing. It’s up to you what you like more, but I’d pick the list comprehension!

30. Dictionary and set comprehensions

With all the attention that goes to list comprehensions, you’d almost forget that you can use the same language construct for dictionaries and sets.

A dictionary requires a key and a value. Otherwise, it’s the same trick again:

>>> {x: x**2 for x in (2, 4, 6)}
{2: 4, 4: 16, 6: 36}

The only difference is that we define both the key and value in the expression part.

The syntax for a set comprehension is not much different from a list comprehension. We just use curly brackets instead of square brackets:

{ <expression> for item in list if <conditional> }

For example:

>>> {s for s in range(1,5) if s % 2}
{1, 3}

Thank you for reading. I hope you enjoyed this as much as I enjoyed writing it! Hungry for more? Try this:

Software developer by day, writer at night. Webmaster at https://python.land