Photo by Timothy Dykes on Unsplash
Show me your code and I will tell you who you are.
This article will fix the bad habits you have stuck to over the years or brought from other programming languages.
Manual String Formatting
Most of the time you see beginner Pythonistas using the +
sign when combining two strings.
>>> name = "Ridwan"
>>> age = "22"
>>> print("My Name is " + name + " and I am " + age + " years old")
My Name is Ridwan and I am 22 years old
Instead of using the +
sign, use the f
string which makes your code readable, concise, and less prone to errors.
>>> print(f"My Name is {name} and I am {age} years old")
My Name is Ridwan and I am 22 years old
Using Default Mutable Arguments
In Python, anytime you pass a mutable value as an argument in a function, the default argument is mutated anytime the function is called. These mutable arguments are usually lists or dictionaries.
Look at the example below;
>>> def append(n, l=[]):
... l.append(n)
... return l
...
After defining the append function with a mutable argument l = []
, anytime you call the function with a value of n
, it changes the default value of l
.
>>> l1 = append(0)
>>> l1
[0]
When next you call the function with a different value of n
, you are going to see the previous value you used appended to the empty list argument.
>>> l2 = append(1)
>>> l2
[0, 1]
You can solve this problem by rewriting the code as:
>>> def append(n, l = None):
... if l is None:
... l = []
... l.append(n)
... return l
...
>>> l1 = append = [0]
>>> l2 = append = [1]
>>> l1,l2
([0], [1])
Now the argument l
is set to None
, anytime the function is called even if l
is mutated, it is reassigned as None
and then given the value of an empty list.
Not Using Comprehensions
Python comprehensions provides you a short and concise way of way of constructing sequences, last time I checked, Python supports 4 types of comprehension;
List Comprehensions
Dictionary Comprehensions
Set Comprehensions
Generator Comprehensions
You can read more about them here.
The code below divides the values in a dictionary by 2,
>>> numbers = {}
>>> for i in range(10):
... numbers[i] = i/2
...
>>> numbers
{0: 0.0, 1: 0.5, 2: 1.0, 3: 1.5, 4: 2.0, 5: 2.5, 6: 3.0, 7:
3.5, 8: 4.0, 9: 4.5}
The above code can be written in a single line as,
>>> {i: i/2 for i in range(10)}
{0: 0.0, 1: 0.5, 2: 1.0, 3: 1.5, 4: 2.0, 5: 2.5, 6: 3.0, 7:
3.5, 8: 4.0, 9: 4.5}
So stop making life difficult for yourself and start using comprehension.
Checking for Equality instead of Identity
Given,
a = [1, 2, 3]
b = [1, 2, 3]
If I ask you to check if the two variables are identical, the first thing to come to your mind is,
>>> a == b
True
The thing is that you need to know the difference between Identity and Equality.
Two variables can be equal but not identical.
If you check the memory addresses of a and b,
>>> id(a), id(b)
(1838093945856, 1838093487488)
You can see that they both have different addresses despite the fact that they have the same object.
This is the reason why, when you run,
>>> a == b
True
You get True
, but when you run
>>> a is b
False
You get False
, a
and b
are equal but not identical.
In the case where you have,
>>> c = [1,2,3]
>>> d = c
>>> id(c), id(d)
(1838089019712, 1838089019712)
You can see, c
and d
are both equal and identical, the object in c
is also assigned to d
.
>>> c == d
True
>>> c is d
True
This implies c
and d
have both the same value and memory addresses.
Hence you can say c
is identical and equal to d
.
All this epistle is to make you know the difference between is
and ==
, the former is used in checking identity while the latter is used in checking equality.
All Identical variables are equal but not all Equal variables are identical
Not Using Tuple Unpacking
Anytime you create a tuple in Python, it is known as packing a tuple,
>>> a_tuple = 1,2,3
>>> a_tuple
(1, 2, 3)
These values can be extracted back into various variables by unpacking
>>> x = a_tuple[0]
>>> y = a_tuple[1]
>>> z = a_tuple[2]
>>> print(x, y, z)
1, 2, 3
Instead of unpacking the elements in a tuple using multiple lines of code, you can do it in a single line of code.
>>> x,y,z = a_tuple
>>> print(x, y, z)
1, 2, 3
Creating Your Own Index Counter Variable
This one is common from those coming from other programming languages, you are asked to create a index counter variable and you type something like;
>>> a_list = [1,2,3,4,5,6,7,8,9,10]
>>> index = 0
>>> for elem in a_list:
... print(index, elem)
... index += 1
...
0 1
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 9
9 10
Instead, use the enumerate function to make your code look Pythonic;
>>> for index, elem in enumerate(a_list):
... print(index, elem)
...
0 1
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 9
9 10
Using Print Statement Instead of the Logging Module
This might not matter in small projects, but will surely help you in larger projects.
Instead of littering your code with print statements, use the logging instead.
>>> print('This is a warning message')
This is a warning message
>>> print('This is an error message')
This is an error message
>>> print('This is a critical message')
This is a critical message
Logging helps display useful messages to your users to add more context and understanding to what is happening in the code base.
>>> import logging
>>> logging.warning('This is a warning message')
WARNING:root:This is a warning message
>>> logging.error('This is an error message')
ERROR:root:This is an error message
>>> logging.critical('This is a critical message')
CRITICAL:root:This is a critical message
Importing functions and classes in a named module with import *
This bad habit most at times is common among newbies.
Importing using import *
corrupts your namespace by importing all the functions and classes from that named module into your code which is likely to conflict with the functions you define or functions of other libraries imported.
Not Following pep8
Most of us are guilty of this,
Before I get canceled 😂, I know some of my codes in this article might have broken the rules of PEP-8, but the truth is bitter and needs to be told, following PEP-8 style and guidelines makes it easier for others to read and understand your code.
Not Recommended
>>> def function():
... x = [1,2,3]
... y= [2,3,5]
... z = [1, 2,3]
...
>>> def value(x = 7):
... ...
...
Recommended
>>> def function():
... x = [1, 2, 3]
... y = [2, 3, 5]
... z = [1, 2, 3]
...
>>> def number(x=7):
... ...
...
To read more about the PEP-8 style and guidelines, check out this article.
Thanks for reading. Hope the article was worth your time.
Top comments (0)