0% found this document useful (0 votes)
154 views

30 Python Best Practices, Tips, and Tricks by Erik Van Baaren Python Land Medium

This document provides 30 tips for improving Python skills and knowledge. It begins with tips on using Python 3, checking the Python version, using IPython for an enhanced shell experience, list comprehensions for cleaner code, checking memory usage, returning multiple values from functions, using data classes, in-place variable swapping, merging dictionaries, string manipulation, slicing lists, and more. Overall, the tips cover a wide range of Python best practices and techniques for both beginners and experienced Python developers.

Uploaded by

a.giacchetto
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
154 views

30 Python Best Practices, Tips, and Tricks by Erik Van Baaren Python Land Medium

This document provides 30 tips for improving Python skills and knowledge. It begins with tips on using Python 3, checking the Python version, using IPython for an enhanced shell experience, list comprehensions for cleaner code, checking memory usage, returning multiple values from functions, using data classes, in-place variable swapping, merging dictionaries, string manipulation, slicing lists, and more. Overall, the tips cover a wide range of Python best practices and techniques for both beginners and experienced Python developers.

Uploaded by

a.giacchetto
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 23

You have 2 free member-only stories left this month.

Sign up for Medium and get an extra one

30 Python Best Practices, Tips, And Tricks


Improve your Python knowledge and skills

Erik van Baaren Follow


Jun 17 · 9 min read

Here are 30 Python best practices, tips, and tricks. I’m sure they’ll help you
procrastinate your actual work, and still learn something useful in the process.

1. Use Python 3
In case you missed it: Python 2 is officially not supported as of January 1, 2020.
This guide has a bunch of examples that only work in Python 3. If you’re still on Python
2.7, upgrade now.

If you’re on MacOS, you can use Homebrew to painlessly upgrade Python.

2. 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:

1 if not sys.version_info > (2, 7):


2 # berate your user for running a 10 year
3 # python version
4 elif not sys.version_info >= (3, 5):
5 # Kindly tell your user (s)he needs to upgrade
6 # because you're using 3.5 features

check_python_version.py hosted with ❤ by GitHub view raw

3. Use IPython
Screenshot by author

IPython is basically an enhanced shell. It’s the core of the very popular Jupyter
Notebook. It’s worth it just for the autocompletion alone, but there is much more. I like
it too for all the magic commands that are built-in. Here are a few :

%cd — to change the current working directory

%edit — to open an editor and execute the code you typed in after closing the
editor

%env — to show the current environment variables

%pip install [pkgs] — to install packages without leaving the interactive shell

%time and %timeit — to time the execution of Python code

Read the full list here.


Another useful feature is referencing the output of a previous command. In and Out
are actual objects. You can use the output of the 3rd command by using Out[3] .

Install IPython with:

pip3 install ipython

4. 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:

1 mylist = [i for i in range(10)]


2 print(mylist)
3 # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

list_comprehensions_1.py hosted with ❤ by GitHub view raw

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

1 squares = [x**2 for x in range(10)]


2 print(squares)
3 # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

list_comprehensions_2.py hosted with ❤ by GitHub view raw

Or even call an external function:

1 def some_function(a):
2 return (a + 5) / 2
3
4 my_formula = [some_function(i) for i in range(10)]
5 print(my_formula)
6 # [2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0]

list comprehensions 3 py hosted with ❤ by GitHub view raw


list_comprehensions_3.py hosted with ❤ by GitHub view raw

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

1 filtered = [i for i in range(20) if i%2==0]


2 print(filtered)
3 # [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

list_comprehensions_4.py hosted with ❤ by GitHub view raw

For a more thorough explanation, head over to this list comprehension tutorial.

5. Check memory usage of your objects


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

1 import sys
2
3 mylist = range(0, 10000)
4 print(sys.getsizeof(mylist))
5 # 48

check_memory_usage_1.py hosted with ❤ by GitHub view raw

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:

1 import sys
2
3 myreallist = [x for x in range(0, 10000)]
4 print(sys.getsizeof(myreallist))
5 # 87632

check_memory_usage_2.py hosted with ❤ by GitHub view raw


6. 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:

1 def get_user(id):
2 # fetch user from database
3 # ....
4 return name, birthdate
5
6 name, birthdate = get_user(4)

return_multiple_variables.py hosted with ❤ by GitHub view raw

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

7. Use 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:

1 from dataclasses import dataclass


2
3 @dataclass
4 class Card:
5 rank: str
6 suit: str
7
8 card = Card("Q", "hearts")
9
10 print(card == card)
11 # True
12
13 print(card.rank)
14 # 'Q'
15
16 print(card)
17 Card(rank='Q', suit='hearts')

dataclass.py hosted with ❤ by GitHub view raw

If you think this is useful, read this Python data class tutorial with lots of examples. It’s
also good to know there’s also a more advanced version of data classes offered by
Python Attrs.

8. In place variable swapping


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

1 a = 1
2 b = 2
3 a, b = b, a
4 print (a)
5 # 2
6 print (b)
7 # 1

in_place_variable_swapping.py hosted with ❤ by GitHub view raw

9. Merging dictionaries (Python 3.5+)


Since Python 3.5, it became easier to merge dictionaries:

1 dict1 = { 'a': 1, 'b': 2 }


2 dict2 = { 'b': 3, 'c': 4 }
3 merged = { **dict1, **dict2 }
4
5 print (merged)
6 # {'a': 1, 'b': 3, 'c': 4}
7
8 # Python >= 3.9 only
9 merged = dict1 | dict2
10
11 print (merged)
12 # {'a': 1, 'b': 3, 'c': 4}

merging_dicts.py hosted with ❤ by GitHub view raw

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

10. String to title case


This is just one of those lovely gems:

1 mystring = "10 awesome python tricks"


2 print(mystring.title())
3 '10 Awesome Python Tricks'

string_to_titlecase.py hosted with ❤ by GitHub view raw

11. 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:

1 mystring = "The quick brown fox"


2 mylist = mystring.split(' ')
3 print(mylist)
4 # ['The', 'quick', 'brown', 'fox']

string_to_list.py hosted with ❤ by GitHub view raw

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() .

12. 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:

1 mylist = ['The', 'quick', 'brown', 'fox']


2 mystring = " ".join(mylist)
3 print(mystring)
4 # 'The quick brown fox'

list_to_string.py hosted with ❤ by GitHub view raw

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.

13. Emoji

Image by Pixaline on Pixabay


This one will either impress or repulse, depending on who’s looking. On a more serious
note, this can come in handy especially when analyzing social media data.

First, install the emoji module:

pip3 install emoji

With this installed, you can do as follows:

1 import emoji
2 result = emoji.emojize('Python is :thumbs_up:')
3 print(result)
4 # 'Python is 👍'
5
6 # You can also reverse this:
7 result = emoji.demojize('Python is 👍')
8 print(result)
9 # 'Python is :thumbs_up:'

emoji.py hosted with ❤ by GitHub view raw

Visit the emoji package page for more examples and documentation.

14. Slicing a list

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 string for end

1 for step

Here are some examples:


1 # We can easily create a new list from
2 # the first two elements of a list:
3 first_two = [1, 2, 3, 4, 5][0:2]
4 print(first_two)
5 # [1, 2]
6
7 # And if we use a step value of 2,
8 # we can skip over every second number
9 # like this:
10 steps = [1, 2, 3, 4, 5][0:5:2]
11 print(steps)
12 # [1, 3, 5]
13
14 # This works on strings too. In Python,
15 # you can treat a string like a list of
16 # letters:
17 mystring = "abcdefdn nimt"[::2]
18 print(mystring)
19 # 'aced it'

list_slicing.py hosted with ❤ by GitHub view raw

15. 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:

1 revstring = "abcdefg"[::-1]
2 print(revstring)
3 # 'gfedcba'
4
5 revarray = [1, 2, 3, 4, 5][::-1]
6 print(revarray)
7 # [5, 4, 3, 2, 1]

reversing_stuff.py hosted with ❤ by GitHub view raw

16. Display kittens


I finally found a good excuse to include kittens in one of my articles! You, however,
might use it to display graphs and such. First, install Pillow, a fork of the Python Image
Library:

pip3 install Pillow

Now download this image to a file called kittens.jpg:

Image by TheDigitalArtist on Pixabay

You can use the following code to display the image from your Python code:

1 from PIL import Image


2
3 im = Image.open("kittens.jpg")
4 im.show()
5 print(im.format, im.size, im.mode)
6 # JPEG (1920, 1357) RGB

pillow.py hosted with ❤ by GitHub view raw

Or you can do it right from IPython:


It’s me, looking at kittens

Pillow can do a lot more than displaying the image. It can analyze, resize, filter,
enhance, morph, etcetera. See the documentation for all its features.

17. 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.

1 def upper(s):
2 return s.upper()
3
4 mylist = list(map(upper, ['sentence', 'fragment']))
5 print(mylist)
6 # ['SENTENCE', 'FRAGMENT']
7
8 # Convert a string representation of
9 # a number into a list of ints.
10 list_of_ints = list(map(int, "1234567"))
11 print(list_of_ints)
12 # [1, 2, 3, 4, 5, 6, 7]

map.py hosted with ❤ by GitHub view raw

Take a look at your own code and see if you can use map() instead of a loop
somewhere! Many Python programmers will prefer to use list comprehensions where
possible, though, since it is considered to be more pythonic.

18. 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:

1 mylist = [1, 1, 2, 3, 4, 5, 5, 5, 6, 6]
2 print (set(mylist))
3 # {1, 2, 3, 4, 5, 6}
4
5 # And since a string can be treated like a
6 # list of letters, you can also get the
7 # unique letters from a string this way:
8 print (set("aaabbbcccdddeeefff"))
9 # {'a', 'b', 'c', 'd', 'e', 'f'}

set.py hosted with ❤ by GitHub view raw

19. Find the most frequently occurring value


To find the most frequently occurring value in a list or string:

1 test = [1, 2, 3, 4, 2, 2, 3, 1, 4, 4, 4]
2 print(max(set(test), key = test.count))
3 # 4

most_frequent.py hosted with ❤ by GitHub view raw

Do you understand why this works? Try to figure it out for yourself before reading on.

You didn’t try, did you? I’ll tell you anyway:

max() will return the highest value in a list. The key argument takes a single
argument function to customize the sort order, in this case, it’s test.count. The
function is applied to each item on the iterable.

test.count is a built-in function of list. It takes an argument and will count the
number of occurrences for that argument. So test.count(1) will return 2 and
test.count(4) returns 4.

set(test) returns all the unique values from test, so {1, 2, 3, 4}

So what we do in this single line of code is take all the unique values of test, which is
{1, 2, 3, 4} . Next, max will apply the list.count function to them and return the
maximum value.

And no — I didn’t invent this one-liner.

20. Create a progress bar


You can create your own progress bar, which is fun to do. But it’s quicker to use the
progress package:

pip3 install progress

Now you can create a progress bar with minimal effort:

1 from progress.bar import Bar


2
3 bar = Bar('Processing', max=20)
4 for i in range(20):
5 # Do some work
6 bar.next()
7 bar.finish()
progress_bar.py hosted with ❤ by GitHub view raw

The following animation demonstrates all the available progress types:

Animation by Giorgos Verigakis from progress

21. Use the _ in an interactive shell


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

In [1]: 3 * 3
Out[1]: 9

In [2]: _ + 3
Out[2]: 12

This works in the Python shell (REPL) too. In addition, the IPython shell allows you to
use Out[n] to get the value of the expression In[n] . E.g., Out[1] would give us the
number 9 in the example above.
22. Quickly create a web server
You can quickly start a web server, serving the contents of the current directory:

python3 -m http.server

This is useful if you want to share some stuff with a co-worker or want to test a simple
HTML site. Don’t use it for anything that comes close to a production system, though.

23. Multi-Line Strings


Although you can use triple quotes to include multi-line strings in your code, it’s not
ideal. Everything you put between the triple quotes becomes the string, including the
formatting, as you can see below.

I prefer another method, which concatenates multiple lines together, allowing you to
format your code nicely. The only downside is that you need to explicitly put in
newlines:

1 s1 = """Multi line strings can be put


2 between triple quotes. It's not ideal
3 when formatting your code though"""
4
5 print (s1)
6 # Multi line strings can be put
7 # between triple quotes. It's not ideal
8 # when formatting your code though
9
10 s2 = ("You can also concatenate multiple\n"
11 "strings this way, but you'll have to\n"
12 "explicitly put in the newlines")
13
14 print(s2)
15 # You can also concatenate multiple
16 # strings this way, but you'll have to
17 # explicitly put in the newlines

multiline_strings.py hosted with ❤ by GitHub view raw


24. 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!"

25. Counting occurrences


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

1 from collections import Counter


2
3 mylist = [1, 1, 2, 3, 4, 5, 5, 5, 6, 6]
4 c = Counter(mylist)
5 print(c)
6 # Counter({1: 2, 2: 1, 3: 1, 4: 1, 5: 3, 6: 2})
7
8 # And it works on strings too:
9 print(Counter("aaaaabbbbbccccc"))
10 # Counter({'a': 5, 'b': 5, 'c': 5})

counter.py hosted with ❤ by GitHub view raw

26. Chaining of comparison operators


You can chain comparison operators in Python, creating more readable and concise
code:
1 x = 10
2
3 # Instead of:
4 if x > 5 and x < 15:
5 print("Yes")
6 # yes
7
8 # You can also write:
9 if 5 < x < 15:
10 print("Yes")
11 # Yes

chaining_comparisons.py hosted with ❤ by GitHub view raw

27. Add some color

Screenshot by Jonathan Hartley from Colorama

With Colorama, you can add some color to your terminal.

1 from colorama import Fore, Back, Style


2
3 print(Fore.RED + 'some red text')
4 print(Back.GREEN + 'and with a green background')
5 print(Style.DIM + 'and in dim text')
6 print(Style.RESET_ALL)
7 print('back to normal now')

colorama.py hosted with ❤ by GitHub view raw

28. Working with dates


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.

1 from dateutil.parser import parse


2
3 logline = 'INFO 2020-01-01T00:00:01 Happy new year, human.'
4 timestamp = parse(logline, fuzzy=True)
5 print(timestamp)
6 # 2020-01-01 00:00:01

dateutil.py hosted with ❤ by GitHub view raw

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

29. Integer division


By Torindkflt — Public Domain

In Python 2, the division operator ( / ) defaults to an integer division, unless one of the
operands is a floating-point number. So you have this behavior:

# Python 2
5 / 2 = 2
5 / 2.0 = 2.5

In Python 3, the division operator defaults to a floating-point division and the //


operator has become an integer division. So we get:

Python 3
5 / 2 = 2.5
5 // 2 = 2

For the complete motivation behind this change, you should read PEP-0238.
30. Charset detection with chardet
You can use the chardet module to detect the charset of a file. This can come in very
useful when analyzing big piles of random text. Install with:

pip install chardet

You now have an extra command-line tool called chardetect, which can be used like
this:

chardetect somefile.txt
somefile.txt: ascii with confidence 1.0

You can also use the library programmatically, check out the docs.

That’s it! 30 tips, tricks, and best practices. I hope you enjoyed them as much as I
enjoyed creating the list. If you have anything to add, feel free to leave a comment!

Sign up for Python Land Newsletter


By Python Land

Get updated on our best articles. No spam. No selling of your data. Promised! Take a look.

Your email

Get this newsletter

By signing up, you will create a Medium account if you don’t already have one. Review our Privacy Policy for more information
about our privacy practices.

Python Programming Data Science Software Development Tricks


About Write Help Legal

Get the Medium app

You might also like