9 Most Useful Python Tricks

Some of the most useful tricks that you can find in the Python ecosystem.

Sergio Daniel Cortez Chavez
Python in Plain English

--

Photo by Amol Tyagi on Unsplash

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, and tuple) and some non-sequence types like dict, 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.

List comprehension:

names = ['John', 'Bard', 'Jessica' 'Andres']
lower_names = [name.lower() for name in names]

Set comprehension:

names = ['John', 'Bard', 'Jessica' 'Andres']
lower_names = {name.lower() for name in names}

Dictionary comprehension:

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.

--

--