Top 25 Python Clean Code Practices

Top 25 Python Clean Code Practices

CodeProgrammer

#Top_25_Python_Clean_Code_Practices
#Python #CleanCode #Programming #BestPractices #Developer

Use List Comprehensions for Creating Lists
* More concise and readable than for loops.

Bad:

squares = []
for i in range(10):
squares.append(i * i)

Good:
squares = [i * i for i in range(10)]

Use enumerate to Get Both Index and Value
* Avoid manual index tracking.

Bad:

items = ["a", "b", "c"]
i = 0
for item in items:
print(i, item)
i += 1

Good:
items = ["a", "b", "c"]
for i, item in enumerate(items):
print(i, item)

Use snake_case for Variables and Functions
* Follows the PEP 8 style guide.

Bad:

def calculateTotalSum(itemsList):
# ...

Good:
def calculate_total_sum(items_list):
# ...

Use Meaningful Variable Names
* Code is read more often than it's written. Clarity is key.

Bad:

d = 20 # elapsed time in days

Good:
elapsed_time_in_days = 20

Use f-Strings for String Formatting
* They are faster and more readable than % or .format().

Bad:

name = "Alice"
age = 30
print("My name is %s and I am %d years old." % (name, age))
print("My name is {} and I am {} years old.".format(name, age))

Good:
name = "Alice"
age = 30
print(f"My name is {name} and I am {age} years old.")

Use zip to Iterate Over Multiple Iterables
* Cleanly combines multiple lists for parallel iteration.

Bad:

list1 = [1, 2, 3]
list2 = ['a', 'b', 'c']
for i in range(len(list1)):
print(list1[i], list2[i])

Good:
list1 = [1, 2, 3]
list2 = ['a', 'b', 'c']
for num, letter in zip(list1, list2):
print(num, letter)

Unpack Tuples and Sequences
* Assign multiple variables in a single, readable line.

Bad:

person = ("John", 35, "Engineer")
name = person[0]
age = person[1]
job = person[2]

Good:
person = ("John", 35, "Engineer")
name, age, job = person

Use the in Keyword for Membership Testing
* It's idiomatic, readable, and often faster.

Bad:

found = False
for item in my_list:
if item == target:
found = True
break

Good:
found = target in my_list

Use with open() for File Handling
* It automatically handles closing the file, even if errors occur.

Bad:

f = open('my_file.txt', 'w')
f.write('hello')
f.close()

Good:
with open('my_file.txt', 'w') as f:
f.write('hello')

Use Truthiness to Check for Empty Containers
* Empty sequences (lists, strings, tuples) and collections (dicts, sets) are False in a boolean context.

Bad:

my_list = []
if len(my_list) == 0:
print("List is empty")

Good:
my_list = []
if not my_list:
print("List is empty")

Use _ for Throwaway Variables
* Signals that a variable is intentionally unused.

Bad:

for i in range(5):
print("Hello")

Good:
for _ in range(5):
print("Hello")

Use Dictionary's .get() for Safe Key Access
* Avoids a KeyError by providing a default value if the key is missing.

Bad:

my_dict = {'a': 1}
if 'b' in my_dict:
value = my_dict['b']
else:
value = 0

Good:
my_dict = {'a': 1}
value = my_dict.get('b', 0)

Return Early from Functions (Guard Clauses)
* Reduces nesting and improves readability by handling edge cases at the beginning.

Bad:

def process(data):
if data is not None:
# complex logic here...
return result
else:
return None

Good:
def process(data):
if data is None:
return None
# complex logic here...
return result

Chain Comparison Operators
* Makes range checks more mathematical and readable.

Bad:

x = 5
if x > 0 and x < 10:
print("x is in range")

Good:
x = 5
if 0 < x < 10:
print("x is in range")

Use Ternary Operators for Simple Conditions
* A concise way to write a simple if-else statement.

Bad:

if score > 60:
result = "Pass"
else:
result = "Fail"

Good:
result = "Pass" if score > 60 else "Fail"

Use Sets for Uniqueness and Math Operations
* Finding unique items or intersections is much faster with sets.

Bad:

my_list = [1, 2, 2, 3, 4, 4, 4]
unique_list = []
for item in my_list:
if item not in unique_list:
unique_list.append(item)

Good:
my_list = [1, 2, 2, 3, 4, 4, 4]
unique_list = list(set(my_list))

Don't Use Mutable Default Arguments
* Default arguments are evaluated once. A mutable object like a list will be shared across all calls.

Bad (causes unexpected behavior):

def add_item(item, items_list=[]):
items_list.append(item)
return items_list

Good:
def add_item(item, items_list=None):
if items_list is None:
items_list = []
items_list.append(item)
return items_list

Use Type Hinting for Clarity
* Improves code readability and allows static analysis tools to catch errors.

Bad:

def greet(name):
return "Hello, " + name

Good:
def greet(name: str) -> str:
return "Hello, " + name

Create Generators for Large Datasets
* Use () instead of [] to create a generator expression, which yields items one by one, saving memory.

Bad (creates a huge list in memory):

total = sum([i*i for i in range(10000000)])

Good (memory efficient):
total = sum(i*i for i in range(10000000))

Join Strings with .join()
* Far more efficient than repeated concatenation with +.

Bad:

words = ["hello", "world", "from", "python"]
sentence = ""
for word in words:
sentence += word + " "

Good:
words = ["hello", "world", "from", "python"]
sentence = " ".join(words)

Use is for Identity and == for Equality
* is checks if two variables point to the same object in memory. == checks if the objects have the same value. Use is for singletons like None, True, False.

Not recommended:

if my_var == None:
#...

Good:
if my_var is None:
#...

Leverage collections.Counter for Counting
* A highly efficient and convenient way to count hashable objects.

Bad:

counts = {}
for item in my_list:
if item in counts:
counts[item] += 1
else:
counts[item] = 1

Good:
from collections import Counter
counts = Counter(my_list)

Be Specific in except Blocks
* Catching a generic Exception can hide bugs. Catch only the exceptions you expect.

Bad:

try:
result = 10 / 0
except Exception:
print("An error occurred")

Good:
try:
result = 10 / 0
except ZeroDivisionError:
print("Cannot divide by zero")

Use if __name__ == "__main__"
* Allows a script to be both run directly and imported by other modules without running the script's code automatically.

Good Practice:

def main():
print("Running main function.")

if __name__ == "__main__":
main()

Use Dictionary Comprehensions
* Just like list comprehensions, they provide a concise way to create dictionaries.

Bad:

my_dict = {}
for i in range(5):
my_dict[i] = i * i

Good:
my_dict = {i: i * i for i in range(5)}

Report Page