Python Functools & Itertools: 7 outils super pratique pour le code plus intelligent

 Python Functools & Itertools: 7 outils super pratique pour le code plus intelligent



Image de l’auteur | Idéogramme

La bibliothèque standard de Python possède plusieurs utilitaires qui peuvent transformer votre code de maladroit et verbeux à élégant et efficace. Parmi ceux-ci, les modules Functools et Itertools sont souvent très pratiques pour les tâches non triviales.

Aujourd’hui, nous examinerons sept outils essentiels – fonctions et décorateurs – à partir de ces modules qui amélioreront votre code Python.

Commençons.

🔗 Lien vers le code sur github

1 et 1 functools.lru_cache

Vous pouvez utiliser le @lru_cache décorateur pour cacher les résultats de la fonction et pour éviter de répéter des opérations coûteuses.

Voici un exemple:

from functools import lru_cache

@lru_cache(maxsize=128)
def fetch_user_data(user_id):
    # Expensive database call
    return database.get_user(user_id)

# First call hits database, subsequent calls use cache
user = fetch_user_data(123)  # Database call
user = fetch_user_data(123)  # Returns cached result

Comment ça marche: le @lru_cache Les magasins de décorateurs donnent de la mémoire. Quand fetch_user_data(123) est appelé à nouveau, il renvoie le résultat mis en cache au lieu de frapper la base de données. maxsize=128 conserve les 128 résultats les plus récents.

2 itertools.chain

Pour traiter plusieurs itérables en tant que flux continu, vous pouvez utiliser chain.from_iterable() du module Itertools.

Prenons un exemple:

from itertools import chain

# Process multiple log files as one stream
error_logs = ('app.log', 'db.log', 'api.log')
all_lines = chain.from_iterable(open(f) for f in error_logs)

error_count = sum(1 for line in all_lines if 'ERROR' in line)

Comment ça marche: chain.from_iterable() Prend plusieurs itérables et crée un flux continu. Il lit une ligne à la fois.

3 et 3 functools.partial

Les fonctions partielles dans Python sont super utiles lorsque vous devez créer des versions spécialisées de fonctions. Ce qui signifie que vous souhaitez créer des versions de la fonction avec certains arguments déjà définis en utilisant partial du module Functools.

Voici un exemple d’une fonction partielle:

from functools import partial
import logging

def log_event(level, component, message):
    logging.log(level, f"({component}) {message}")

# Create specialized loggers
auth_error = partial(log_event, logging.ERROR, 'AUTH')
db_info = partial(log_event, logging.INFO, 'DATABASE')

# Clean usage
auth_error("Login failed for user")
db_info("Connection established")

Comment ça marche: partial Crée une nouvelle fonction avec quelques arguments pré-remplis. Dans l’exemple, auth_error est essentiellement log_event Avec le niveau et les composants déjà définis, vous n’avez donc qu’à fournir le message.

4 itertools.combinations

Lorsque vous devez générer toutes les combinaisons possibles d’articles pour les tests ou l’optimisation, vous pouvez utiliser combinations du module Itertools.

Considérez l’exemple suivant:

from itertools import combinations

features = ('cache', 'compression', 'cdn')

# Test all pairs of features
for combo in combinations(features, 2):
    performance = test_feature_combo(combo)
    print(f"{combo}: {performance}ms")

Comment ça marche: combinations(features, 2) génère toutes les paires possibles à partir de la liste. Il crée des combinaisons à la demande sans les stocker toutes en mémoire, ce qui le rend efficace pour les grands ensembles de données.

5 functools.singledispatch

Le @singledispatch Le décorateur du module Functools peut vous aider à faire des fonctions qui agissent différemment en fonction du type d’entrée.

Regardez l’extrait de code suivant:

from functools import singledispatch
from datetime import datetime

@singledispatch
def format_data(value):
    return str(value)  # Default

@format_data.register(datetime)
def _(value):
    return value.strftime("%Y-%m-%d")

@format_data.register(list)
def _(value):
    return ", ".join(str(item) for item in value)

# Automatically picks the right formatter
print(format_data(datetime.now()))  # this outputs "2025-06-27"
print(format_data((1, 2, 3)))       # this outputs "1, 2, 3"

Comment cela fonctionne: Python vérifie le type du premier argument et appelle la fonction enregistrée appropriée. Cependant, il utilise la valeur par défaut @singledispatch fonction si aucun gestionnaire spécifique n’existe.

6. itertools.groupby

Vous pouvez regrouper des éléments consécutifs qui partagent la même propriété groupby Fonction d’Itertools.

Considérez cet exemple:

from itertools import groupby

transactions = (
    {'type': 'credit', 'amount': 100},
    {'type': 'credit', 'amount': 50},
    {'type': 'debit', 'amount': 75},
    {'type': 'debit', 'amount': 25}
)

# Group by transaction type
for trans_type, group in groupby(transactions, key=lambda x: x('type')):
    total = sum(item('amount') for item in group)
    print(f"{trans_type}: ${total}")

Comment ça marche: groupby Groupes éléments consécutifs avec la même clé. Il retourne des paires de (key, group_iterator). IMPORTANT: Il ne regroupe que les éléments adjacents, alors triez d’abord vos données si nécessaire.

7 functools.reduce

Vous pouvez utiliser le reduce Fonction du module Functools pour appliquer une fonction cumulativement à tous les éléments d’un itérable pour obtenir une seule valeur.

Prenez l’exemple suivant:

from functools import reduce

# Calculate compound interest
monthly_rates = (1.01, 1.02, 0.99, 1.015)  # Monthly growth rates

final_amount = reduce(lambda total, rate: total * rate, monthly_rates, 1000)
print(f"Final amount: ${final_amount:.2f}")

Comment ça marche: reduce Prend une fonction et l’applique étape par étape: d’abord à la valeur initiale (1000) et au premier taux, puis à ce résultat et au deuxième taux, et ainsi de suite. Il fonctionne bien pour les opérations qui accumulent l’état.

Emballage

Pour résumer, nous avons vu comment vous pouvez utiliser:

  • @lru_cache Lorsque vous avez des fonctions qui sont souvent appelées avec les mêmes arguments
  • itertools.chain Lorsque vous devez traiter plusieurs sources de données comme un seul flux continu
  • functools.partial Pour créer des versions spécialisées de fonctions génériques
  • itertools.combinations Pour une exploration systématique des possibilités
  • @singledispatch Lorsque vous avez besoin d’un comportement de fonction basé sur le type
  • groupby Pour des opérations de regroupement consécutives efficaces
  • reduce pour des agrégations complexes qui accumulent l’état

La prochaine fois que vous vous retrouverez à écrire des boucles verbales ou à un code répétitif, faites une pause et demandez si l’une d’entre elles pourrait fournir une solution plus élégante.

Ce ne sont qu’une poignée d’outils que je trouve utiles. Il y en a beaucoup plus si vous examinez de plus près la bibliothèque standard Python. Alors oui, heureux d’explorer!

Bala Priya C est développeur et écrivain technique d’Inde. Elle aime travailler à l’intersection des mathématiques, de la programmation, de la science des données et de la création de contenu. Ses domaines d’intérêt et d’expertise incluent DevOps, la science des données et le traitement du langage naturel. Elle aime lire, écrire, coder et café! Actuellement, elle travaille sur l’apprentissage et le partage de ses connaissances avec la communauté des développeurs en créant des tutoriels, des guides pratiques, des pièces d’opinion, etc. Bala crée également des aperçus de ressources engageants et des tutoriels de codage.





Source link

Related post