16 Python Tricks To Learn Before You Write Your Next Code
Enes ARSLAN
Posted on March 3, 2023
Python is a versatile and widely-used programming language with a vast array of libraries and frameworks. However, there are some lesser-known Python coding tricks and libraries that can make your life as a developer easier and your code more efficient.
In this blog, we will explore some of these less-known Python tricks that can be incredibly useful but are not widely known. By learning and implementing these tricks, you can save time and effort in your coding and make your code more elegant and efficient. So, let’s dive in and explore these hidden gems of the Python language!
1. Ternary operator
The ternary operator is a shorthand for an if-else statement. The syntax is value_if_true if condition else value_if_false. It's a one-liner that can replace a multi-line if-else statement, making your code more concise.
a = 5
b = 10
max = a if a > b else b
print(max)
#10
The above query checks whether ‘a’ is greater than ‘b’ and returns ‘a’ if true and ‘b’ if false.
2. Enumerate function
The enumerate()
function adds a counter to an iterable and returns it in a form of enumerate object. This function is useful when you want to iterate over a list and also keep track of the index.
fruits = ['apple', 'banana', 'mango']
for index, fruit in enumerate(fruits):
print(index, fruit)
#0 apple
#1 banana
#2 mango
3. Zip function
The zip()
function aggregates elements from each of the iterables and returns an iterator of tuples. This function is useful when you want to iterate over two or more lists simultaneously.
list1 = [1, 2, 3]
list2 = ['a', 'b', 'c']
for x, y in zip(list1, list2):
print(x, y)
#1 a
#2 b
#3 c
4. List comprehensions
List comprehensions are a concise way to create a list from an existing list or any iterable. It’s a one-liner that can replace a for loop, making your code more efficient and readable.
squared_numbers = [x**2 for x in range(1, 6)]
print(squared_numbers)
#[1, 4, 9, 16, 25]
5. Lambda functions
Lambda functions are anonymous functions that are defined using the lambda keyword. They are useful when you need to write small, one-time functions, and you don't want to use the def keyword to define a named function.
add = lambda x, y: x + y
result = add(3, 4)
print(result)
#7
6. Any and all functions
The any()
and all()
functions return True or False based on the truthiness of the elements in an iterable. The any()
function returns True if any element in the iterable is true, and all()
function returns True if all elements in the iterable are true.
numbers = [1, 2, 3, 0, 4]
result = any(numbers) #True
result = all(numbers) # False. 0 is making it false
7. Itertools
The itertools module provides a set of functions to work with iterators and is not widely known. Some of the functions in this module are chain, product, and permutations.
import itertools
numbers = [1, 2, 3]
result = list(itertools.permutations(numbers))
#output all the permutations
#[(1, 2, 3), (1, 3, 2), (2, 1, 3), (2, 3, 1), (3, 1, 2), (3, 2, 1)]
8. Generators
Generators are a type of iterable that generate values on-the-fly, instead of storing them in memory. They are defined using the yield keyword and can be used to create custom iterators.
### Generators created using yield keyword
def fibonacci_series(n):
a, b = 0, 1
for i in range(n):
yield a
a, b = b, a + b
# Driver code to check above generator function
for number in fibonacci_series(10):
print(number)
#0
#1
#1
#2
#3
#5
#8
#13
#21
#34
9. Decorators
Decorators are a way to modify the behavior of a function or a class. They are defined using the @ symbol and can be used to add functionality to a function, such as logging, timing, or authentication.
def log_function(func):
def wrapper(*args, **kwargs):
print(f'Running {func.__name__}')
result = func(*args, **kwargs)
print(f'{func.__name__} returned {result}')
return result
return wrapper
@log_function
def add(x, y):
return x + y
print(add(5,7))
#Running add
#add returned 12
#12
10. Multiple Function Arguments
In Python, you can use the * and ** operator to handle multiple function arguments. The * operator is used to pass a list of arguments as separate positional arguments, and the ** operator is used to pass a dictionary of keyword arguments.
def print_arguments(*args, **kwargs):
print(args)
print(kwargs)
print_arguments(1, 2, 3, name='John', age=30)
#(1, 2, 3)
#{'name': 'John', 'age': 30}
11. Dynamic Importing
You can import a module dynamically using the importlib module. This can be useful when you want to import a module based on user input or configuration.
import importlib
module_name = 'math'
module = importlib.import_module(module_name)
result = module.sqrt(9)
12. Dictionary Comprehensions
Dictionary comprehensions are a concise way to create a dictionary from an existing dictionary or any iterable. It’s a one-liner that can replace a for loop, making your code more efficient and readable.
squared_numbers = {x: x**2 for x in range(1, 6)}
print(squared_numbers)
#{1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
13. Callable Objects
In Python, anything that can be called a function is called a callable object. This includes functions, methods, classes, and even objects that define the call method.
class Adder:
def __call__(self, x, y):
return x + y
adder = Adder()
result = adder(3, 4)
print(result)
#7
14. You can separate big numbers/characters with the underscore
Big numeric numbers are hard to interpret, so python has a great capability to put underscore to make the numbers more readable.
num_test = 100_345_405 # this is the number
print(num_test)
## 100345405
15. Merge 2 dictionaries quickly
We can quickly merge 2 dictionaries in python using the following piece of code.
dictionary_one = {"a": 1, "b": 2}
dictionary_two = {"c": 3, "d": 4}
merged = {**dictionary_one, **dictionary_two}
print(merged)
# {'a': 1, 'b': 2, 'c': 3, 'd': 4}
16. Lists, sets, and dictionaries are mutable
Mutable means that we can change or update the object(list, set or dictionary) without changing the pointer of the object in the memory. Let’s see it in action.
In the below example, we are updating the cities list by appending a new city. We can see that the ID (object pointer) remains the same. The same is true for the sets and dictionary
cities = ["Munich", "Zurich", "London"]
print(id(cities)) # 2797174365184
cities.append("Berlin")
print(id(cities)) # 2797174365184
####Sets
my_set = {1, 2, 3}
print(id(my_set)) # 2797172976992
my_set.add(4)
print(id(my_set)) # 2797172976992
###Dictionary
thisdict = {
"brand": "Ford",
"model": "Mustang",
"year": 1964
}
print(id(thisdict)) #2797174128256
thisdict["engine"] = "2500cc"
print(id(thisdict)) #2797174128256
Thanks for reading . . .
If you find my post useful, you can follow me
If you want to see my latest code you can follow me on GitHub too.
Posted on March 3, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.