9 Most Useful Python Tricks
Some of the most useful tricks that you can find in the Python ecosystem.
This is a fast guide for some of the most useful tricks that you can find in the Python ecosystem. Most of the tips use only packages from the standard library, but some others refer to third-party packages.
Before starting with the content of the post, you must understand the concept of Iterables in Python.
According to the Python glossary, an Iterable is:
An object capable of returning its members one at a time. Examples of iterables include all sequence types (such as
list
,str
, andtuple
) and some non-sequence types likedict
, file objects, and objects of any classes you define with an__iter__()
method or with a__getitem__()
method that implements Sequence semantics.
This is an important concept to remember, because many of the tips that I going to show you, use the itertools
package. The itertools
modules give some function that receives Iterable
objects and not only lists like the examples that I am going to show you.
Trick 1
Do you need to generate a list, set, or dict from another source by only applying a simple function or method?. Use the comprehension style.
names = ['John', 'Bard', 'Jessica' 'Andres']
lower_names = [name.lower() for name in names]
names = ['John', 'Bard', 'Jessica' 'Andres']
lower_names = {name.lower() for name in names}
names = ['John', 'Bard', 'Jessica' 'Andres']
origina_lower = {name: name.lower() for name in names}
Note. A personal recommendation is to use the comprehension style only when the number of components is not more than 3.
Trick 2
Sometimes you need to get all the possible combinations between two lists of objects. Your first attempt might look something like this:
l1 = [1, 2, 3]
l2 = [4, 5, 6]combinations = []for e1 in l1:
for e2 in l2:
combinations.append((e1, e2))# Or with list comprehensioncombinations = [(e1, e2) for e1 in l1 for e2 in l1]
This is fine, but the standard package itertools
give you the product
function which gives the same result.
from itertools import productl1 = [1, 2, 3]
l2 = [4, 5, 6]combinatios = product(l1, l2)
Trick 3
Other times, you have a list of elements, and you need to compare or apply some operation between each pair of adjacent elements, this is sometimes named the sliding window of 2 elements.
from itertools import tee
from typing import Iterable
def window2(iterable: Iterable):
it, offset = tee(iter(iterable))
next(offset)
return zip(it, offset)l = [1, 2, 3, 4, 5, 6]window2(l) // Is the same that: ((1,2), (2,3), (3, 4), ...)
Trick 4
Sometimes you just need a class to store information and you don’t like the idea of having to create a class and define its __init__
method. In this case, your best option is dataclass
.
from dataclasses import dataclass
@dataclass
class Person:
name: str
age: int
address: str
This creates a class with a default constructor that receives the fields in the same order that you declare.
person = Person(name='John', age=12, address='...')
Another advantage of dataclass
is that by default, generates special methods like __str__
, __repr__
, __eq__
, etc. For a complete tour of dataclasses
, check this post.
Note. Is important to know that the type annotations (str, int, etc) do not force the type of the values you pass in the constructor to be of this type.
Trick 5
Sometimes you like the idea of dataclass
, but you can take advantage of operating over the object as it is were a tuple. One option is to use collections.namedtuple
, but exists a version more similar to dataclass
.
from typing import NamedTuple
class Coordinate(NamedTuple):
x: int
y: int
This defines a normal class that can act as a tuple.
coordinate = Coordinate(10, 15)coordinate.x == coordinate[0] // True
coordinate.y == coordinate[1] // True
Trick 6
Other times you have a dataclass
, but you need to validate the input data according to the type annotations. In this case, install the third-party package pydantic and replace from dataclasses import dataclass
by from pydantic.dataclasses import dataclass
.
from pydantic.dataclasses import dataclass
@dataclass
class Person:
name: str
age: int
address: str
This generates a class with input data parsing and validation according to these types that are annotated. Pydantic enforces type hints at runtime and provides user-friendly errors when data is invalid.
Trick 7
In other cases, you need to generate basic statistics about the frequency of the elements in some containers. In this case, you can use the standard structure Counter
that receive an iterable and generate basic statistics according to the frequency of each element.
from collections import Counterl = [1, 1, 2, 3, 4, 4]
frequencys = Counter(l)print(frequencys[1]) // Ouput: 2
print(frequencys[2]) // Ouput: 1
print(frequencys[2323]) // Ouput: 0
Note. Counter gives some other methods like
most_common
for retrieve the most common elements.
Trick 8
Do you need to apply a function over each pair of elements between two lists?. The first intent maybe sees like this:
// declaration of f function
// ....l1 = [1, 2, 3]
l2 = [4, 5, 6]for (e1, e2) in zip(l1, l2):
f(e1, e2)
But the map function can generate a short version:
// declaration of f function
// ....l1 = [1, 2, 3]
l2 = [4, 5, 6]map(f, l1, l2)
Trick 9
Do you need to take one random element from a list?. Use random.choice
.
from random import choicel = [1, 2, 3]
random = choice(l)
Do you need more than one?. Use random.choices
.
from random import choicesl = [1, 2, 3, 4, 5]
random_elements = choices(l, k=3)
Where the k
argument is the number of random elements that you need.
Thanks for reading!
This is all for this post, I hope the content has been to your liking, see you in the next post.
More content at plainenglish.io. Sign up for our free weekly newsletter. Get exclusive access to writing opportunities and advice in our community Discord.