The Python Way: 10 Tips
Below are 10 useful tips and tricks in Python. Some of them highlight mistakes that are commonly made by beginners to the language.
Note: Let’s assume we’re all using Python 3.
1. List Comprehensions
Suppose you have a list: bag = [1, 2, 3, 4, 5]
Now you want to double each element in the list, so that it looks like this:
[2, 4, 6, 8, 10]
Most beginners, coming from traditional languages will do something like this:
bag = [1, 2, 3, 4, 5]
for i in range(len(bag)):
bag[i] = bag[i] * 2
But there’s a better way:
bag = [elem * 2 for elem in bag]
Cleaner, right? This is called list comprehensions in Python.
For even more on list comprehensions, check out Trey Hunner’s tutorial.
2. Iterating through a list
Again, suppose you have a list. Try to avoid doing this if you can:
bag = [1, 2, 3, 4, 5]
for i in range(len(bag)):
print(bag[i])
Rather, you should do this:
bag = [1, 2, 3, 4, 5]
for i in bag:
print(i)
Since x
is a list, you can iterate over the elements of it. Most of the time,
you won’t need the index of the elements anyways, but in case you do, there’s
the enumerate
function available. It works like this:
bag = [1, 2, 3, 4, 5]
for index, element in enumerate(bag):
print(index, element)
Pretty straightforward.
3. Swapping Elements
This is the way that you’re probably used to if you’re coming from a traditional programming language like Java or C.
a = 5
b = 10
# Swap a and b
tmp = a
a = b
b = tmp
But naturally, in Python there’s usually a better way!
a = 5
b = 10
# Swap a and b
a, b = b, a
Nifty, huh?
4. Initializing a List
Suppose you needed a list of 10
integers set to 0
. You may be tempted to do
something like this:
bag = []
for _ in range(10):
bag.append(0)
Do this instead:
bag = [0] * 10
Ah, how elegant.
Warning: This will create a shallow copy if you’re working with a list within a list.
Example:
bag_of_bags = [[0]] * 5 # [[0], [0], [0], [0], [0]]
bag_of_bags[0][0] = 1 # [[1], [1], [1], [1], [1]]
Oops! It changed all of the lists within x
. We most likely intended to change
the first list.
Do this instead:
bag_of_bags = [[0] for _ in range(5)]
# [[0], [0], [0], [0], [0]]
bag_of_bags[0][0] = 1
# [[1], [0], [0], [0], [0]]
Also note that:
“Premature optimization is the root of all evil”
Ask yourself, do you really need to initialize a list?
5. String building
Often, you’re going to need to print strings. Avoid doing this if you have lots of variables to print:
name = "Raymond"
age = 22
born_in = "Oakland, CA"
string = "Hello my name is " + name + "and I'm " + str(age) + " years old. I was born in " + born_in + "."
print(string)
Ugh, see how messy that was? Instead, you can use .format()
to format your
strings in a nice, cleaner way. Do this instead.
name = "Raymond"
age = 22
born_in = "Oakland, CA"
string = "Hello my name is {0} and I'm {1} years old. I was born in {2}.".format(name, age, born_in)
print(string)
Much better!
6. Returning tuples
Python allows you to return multiple elements in a function. This makes life a lot easier. However, this is common mistake when unpacking the tuple:
def binary():
return 0, 1
result = binary()
zero = result[0]
one = result[1]
This is unnecessary, you should do this instead:
def binary():
return 0, 1
zero, one = binary()
Use an underscore, _
if you don’t need all of the elements returned, like so:
zero, _ = binary()
Efficient!
7. Accessing Dicts
Often, you’ll be updating and adding a key, pair
into dicts
.
You may be tempted to do something like this to avoid the KeyError
when trying
to access a key that doesn’t exist in dict
:
countr = {}
bag = [2, 3, 1, 2, 5, 6, 7, 9, 2, 7]
for i in bag:
if i in countr:
countr[i] += 1
else:
countr[i] = 1
for i in range(10):
if i in countr:
print("Count of {}: {}".format(i, countr[i]))
else:
print("Count of {}: {}".format(i, 0))
But! There’s a better way, using get()
.
countr = {}
bag = [2, 3, 1, 2, 5, 6, 7, 9, 2, 7]
for i in bag:
countr[i] = countr.get(i, 0) + 1
for i in range(10):
print("Count of {}: {}".format(i, countr.get(i, 0)))
You may also be interested in setdefault()
.
Note: Here’s an even simpler although slightly more costly way of doing it:
bag = [2, 3, 1, 2, 5, 6, 7, 9, 2, 7]
countr = dict([(num, bag.count(num)) for num in bag])
for i in range(10):
print("Count of {}: {}".format(i, countr.get(i, 0)))
You can also do this using dict
comprehensions.
countr = {num: bag.count(num) for num in bag}
Both of these ways are more costly because they have to iterate the list every
time count
is called.
8. Using libraries
Chances are, there’s already a library that you can import which does exactly what you want.
For example, in the previous example, we created a function to count the occurrences of numbers in a list. Well, there’s already a library out there that can do this.
from collections import Counter
bag = [2, 3, 1, 2, 5, 6, 7, 9, 2, 7]
countr = Counter(bag)
for i in range(10):
print("Count of {}: {}".format(i, countr[i]))
Some reasons for using libraries:
- Code is correct and tested
- Their algorithm is more than likely to be optimized and thus, runs faster.
- Abstraction: its intentions are clear and well documented, which allows you to focus on what hasn’t been done yet.
- Lastly, it’s there so you don’t have to reinvent the wheel.
9. Slicing/Stepping through a list
You can specify the start
postition and the stop
position like this:
list[start:stop:step]
So, let’s say you want the first 5 elements of a list:
bag = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
for elem in bag[:5]:
print(elem)
This is known as slicing. Since we specified the stop
position of 5, we will
take 5 elements from the list before stopping.
How about last 5 elements in the list?
bag = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
for elem in bag[-5:]:
print(elem)
Didn’t see that one coming huh? The -5
means start from the end of the list
and take 5 elements.
Suppose you wanted to do something to every other element in a list Here’s what you might do:
bag = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
for index, elem in enumerate(bag):
if index % 2 == 0:
print(elem)
Here’s how it should be done:
bag = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
for elem in bag[::2]:
print(elem)
# or equivalently for ranges
bag = list(range(0,10,2))
print(bag)
This is known as stepping through a list. list[::2]
means that you are going
through this list and taking one element for every two steps. Some other cool
things you can do with steps are list[::-1]
which will reverse a list.
10. Tabs vs Spaces
Long version: Mixing spaces and tabs in Python will lead to a disaster. You will
see a IndentationError: unexpected indent
. Regardless of your choice of tabs
or space, you should be consistent with it throughout your files and projects.
One more reason to use spaces rather than tabs is that not all editors treat tabs the same. Depending on the editor you use, tabs may be treated as 2 to 8 spaces.
One thing you can do when writing code is to specify to treat tabs as spaces. This way, you can automatically specify how many spaces a tab is worth. 4 spaces is the norm for most Python users.
TLDR: Use spaces, or treat tabs as spaces for the best of both worlds.
I’d like to thank Reddit users from /r/learnpython:
- /u/treyhunner
- /u/bbatwork
- /u/symmitchry
- /u/dunkler_wanderer
For helping me make some of these tips ever better!
Thanks for reading! If this was helpful for you, please share it with someone. Best of luck learning Python!
Edit: For more tips, click here!
I’ll also recommend this book: Effective Python