La fonction zip() en Python : guide complet avec exemples

Découvrez la fonction zip() en Python : syntaxe, exemples pratiques et bonnes pratiques pour combiner plusieurs itérables efficacement.
8 min de lecture
Believemy logo

La fonction zip() est l'une des fonctions natives les plus puissantes et élégantes de Python. Elle permet de combiner plusieurs itérables (listes, tuples, chaînes de caractères, etc.) en un seul objet itérable de tuples. Cette fonction est indispensable pour tout développeur Python souhaitant manipuler des données de manière efficace et pythonique. Si vous souhaitez maîtriser toutes les subtilités de ce langage, notre formation Python complète vous permettra d'approfondir ces concepts fondamentaux.

 

Définition de la fonction zip()

La fonction zip() prend en paramètre un ou plusieurs itérables et retourne un itérateur de tuples. Chaque tuple contient les éléments correspondants de chaque itérable, regroupés par position (index). Le premier tuple contient les premiers éléments de chaque itérable, le deuxième tuple contient les deuxièmes éléments, et ainsi de suite.

La syntaxe de base de zip() est la suivante :

PYTHON
zip(iterable1, iterable2, ...)

Cette fonction retourne un objet de type zip, qui est un itérateur. Cela signifie qu'il ne génère les tuples qu'à la demande, ce qui est particulièrement efficace en termes de mémoire lorsque vous travaillez avec de grandes quantités de données.

Bon à savoir

La fonction zip() s'arrête dès que l'itérable le plus court est épuisé. Si vous avez des itérables de longueurs différentes, les éléments supplémentaires des itérables plus longs seront ignorés.

 

Exemples pratiques de zip()

Combiner deux listes

L'utilisation la plus courante de zip() est de combiner deux list en parallèle. Voici un exemple simple :

PYTHON
prenoms = ["Alice", "Bob", "Charlie"]
ages = [25, 30, 35]

# Combinaison des deux listes
combines = zip(prenoms, ages)

# Conversion en liste pour afficher le résultat
print(list(combines))
# Résultat : [('Alice', 25), ('Bob', 30), ('Charlie', 35)]

Vous pouvez constater que chaque prénom est associé à l'âge correspondant selon leur position dans les listes respectives.

 

Parcourir plusieurs listes simultanément

L'un des cas d'utilisation les plus fréquents de zip() est de parcourir plusieurs listes en même temps dans une boucle for :

PYTHON
produits = ["Pommes", "Bananes", "Oranges"]
prix = [2.50, 1.80, 3.20]
quantites = [10, 15, 8]

for produit, p, q in zip(produits, prix, quantites):
    total = p * q
    print(f"{produit} : {q} unités à {p}€ = {total}€")

# Résultat :
# Pommes : 10 unités à 2.5€ = 25.0€
# Bananes : 15 unités à 1.8€ = 27.0€
# Oranges : 8 unités à 3.2€ = 25.6€

Cette approche est beaucoup plus élégante et lisible que d'utiliser des indices pour accéder aux éléments de chaque liste.

 

Créer un dictionnaire à partir de deux listes

La fonction zip() est particulièrement utile pour créer un dict à partir de deux listes, l'une contenant les clés et l'autre les valeurs :

PYTHON
cles = ["nom", "age", "ville"]
valeurs = ["Marie", 28, "Paris"]

# Création du dictionnaire
personne = dict(zip(cles, valeurs))

print(personne)
# Résultat : {'nom': 'Marie', 'age': 28, 'ville': 'Paris'}

Cette technique est extrêmement pratique lorsque vous travaillez avec des données tabulaires ou que vous devez transformer des données provenant de différentes sources.

 

Gérer des itérables de longueurs différentes

Comme mentionné précédemment, zip() s'arrête au plus court itérable :

PYTHON
liste1 = [1, 2, 3, 4, 5]
liste2 = ['a', 'b', 'c']

resultat = list(zip(liste1, liste2))
print(resultat)
# Résultat : [(1, 'a'), (2, 'b'), (3, 'c')]
# Les éléments 4 et 5 sont ignorés
Attention

Si vous avez besoin de conserver tous les éléments des itérables de longueurs différentes, utilisez itertools.zip_longest() qui remplit les valeurs manquantes avec une valeur par défaut (généralement None).

 

Utilisation de zip_longest pour des itérables de longueurs différentes

Voici comment utiliser zip_longest() du module itertools :

PYTHON
from itertools import zip_longest

liste1 = [1, 2, 3, 4, 5]
liste2 = ['a', 'b', 'c']

resultat = list(zip_longest(liste1, liste2, fillvalue="N/A"))
print(resultat)
# Résultat : [(1, 'a'), (2, 'b'), (3, 'c'), (4, 'N/A'), (5, 'N/A')]

 

Dézipper avec zip()

Une fonctionnalité souvent méconnue est la possibilité de "dézipper" une liste de tuples en utilisant zip() avec l'opérateur de déballage *. Cette opération inverse le processus de combinaison :

PYTHON
paires = [('Alice', 25), ('Bob', 30), ('Charlie', 35)]

# Dézippage
prenoms, ages = zip(*paires)

print(prenoms)  # ('Alice', 'Bob', 'Charlie')
print(ages)     # (25, 30, 35)

L'opérateur * déballe la liste de tuples, puis zip() regroupe les éléments par position. Le résultat est un tuple pour chaque "colonne" de données.

 

Transposition d'une matrice

Cette technique de dézippage est particulièrement utile pour transposer une matrice (échanger les lignes et les colonnes) :

PYTHON
matrice = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

# Transposition de la matrice
matrice_transposee = list(zip(*matrice))

for ligne in matrice_transposee:
    print(ligne)

# Résultat :
# (1, 4, 7)
# (2, 5, 8)
# (3, 6, 9)

Cette approche est beaucoup plus concise que d'utiliser des boucles imbriquées.

 

Zip avec des générateurs et des itérateurs

La fonction zip() fonctionne parfaitement avec n'importe quel type d'itérable, y compris les générateurs créés avec yield :

PYTHON
def nombres_pairs(n):
    for i in range(0, n, 2):
        yield i

def nombres_impairs(n):
    for i in range(1, n, 2):
        yield i

# Combinaison de deux générateurs
paires_impaires = zip(nombres_pairs(10), nombres_impairs(10))

for pair, impair in paires_impaires:
    print(f"Pair: {pair}, Impair: {impair}")

# Résultat :
# Pair: 0, Impair: 1
# Pair: 2, Impair: 3
# Pair: 4, Impair: 5
# Pair: 6, Impair: 7
# Pair: 8, Impair: 9

Puisque zip() retourne également un itérateur, cette combinaison est très efficace en termes de mémoire car les valeurs sont générées à la demande.

 

Cas d'utilisation avancés

Création de paires consécutives

Vous pouvez utiliser zip() pour créer des paires d'éléments consécutifs dans une liste :

PYTHON
donnees = [10, 20, 30, 40, 50]

# Création de paires consécutives
paires_consecutives = list(zip(donnees, donnees[1:]))

print(paires_consecutives)
# Résultat : [(10, 20), (20, 30), (30, 40), (40, 50)]

Cette technique est très utile pour calculer des différences entre éléments consécutifs ou pour analyser des séries temporelles.

 

Groupement par fenêtres glissantes

Vous pouvez étendre cette idée pour créer des fenêtres glissantes de n'importe quelle taille :

PYTHON
donnees = [1, 2, 3, 4, 5, 6, 7]

# Fenêtres de taille 3
fenetres = list(zip(donnees, donnees[1:], donnees[2:]))

for fenetre in fenetres:
    print(f"Fenêtre: {fenetre}, Moyenne: {sum(fenetre)/3:.2f}")

# Résultat :
# Fenêtre: (1, 2, 3), Moyenne: 2.00
# Fenêtre: (2, 3, 4), Moyenne: 3.00
# Fenêtre: (3, 4, 5), Moyenne: 4.00
# Fenêtre: (4, 5, 6), Moyenne: 5.00
# Fenêtre: (5, 6, 7), Moyenne: 6.00

 

Numérotation des éléments avec enumerate et zip

Vous pouvez combiner zip() avec enumerate() pour obtenir à la fois l'index et les éléments combinés :

PYTHON
noms = ["Alice", "Bob", "Charlie"]
scores = [95, 87, 92]

for index, (nom, score) in enumerate(zip(noms, scores), start=1):
    print(f"{index}. {nom} : {score} points")

# Résultat :
# 1. Alice : 95 points
# 2. Bob : 87 points
# 3. Charlie : 92 points

 

Bonnes pratiques avec zip()

Convertir explicitement en liste si nécessaire

N'oubliez pas que zip() retourne un itérateur, pas une liste. Si vous avez besoin d'accéder aux éléments plusieurs fois ou d'utiliser des opérations de liste, convertissez-le explicitement :

PYTHON
# Mauvaise pratique - l'itérateur est épuisé après la première utilisation
resultat = zip([1, 2], ['a', 'b'])
print(list(resultat))  # [(1, 'a'), (2, 'b')]
print(list(resultat))  # [] - liste vide car l'itérateur est épuisé

# Bonne pratique - convertir immédiatement si nécessaire
resultat = list(zip([1, 2], ['a', 'b']))
print(resultat)  # [(1, 'a'), (2, 'b')]
print(resultat)  # [(1, 'a'), (2, 'b')] - fonctionne toujours

 

Vérifier les longueurs des itérables

En Python 3.10+, vous pouvez utiliser le paramètre strict=True pour générer une erreur si les itérables n'ont pas la même longueur :

PYTHON
# Python 3.10+
liste1 = [1, 2, 3]
liste2 = ['a', 'b']

try:
    resultat = list(zip(liste1, liste2, strict=True))
except ValueError as e:
    print(f"Erreur : {e}")
# Erreur : zip() argument 2 is shorter than argument 1

 

Préférer zip() aux indices

Utilisez toujours zip() plutôt que des indices lorsque vous parcourez plusieurs listes en parallèle. C'est plus lisible et plus pythonique :

PYTHON
# À éviter
noms = ["Alice", "Bob"]
ages = [25, 30]

for i in range(len(noms)):
    print(f"{noms[i]} a {ages[i]} ans")

# À préférer
for nom, age in zip(noms, ages):
    print(f"{nom} a {age} ans")

 

Tableau récapitulatif

OpérationCodeRésultat
Combiner deux listeszip([1,2], ['a','b'])[(1,'a'), (2,'b')]
Dézipperzip(*paires)Tuples séparés
Créer un dictionnairedict(zip(cles, valeurs))Dictionnaire
Longueurs différenteszip_longest()Complète avec fillvalue
Vérification strictezip(..., strict=True)ValueError si longueurs ≠

 

Questions fréquentes

Question

Quelle est la différence entre zip() et itertools.zip_longest() ?

La fonction zip() s'arrête dès que l'itérable le plus court est épuisé, ignorant les éléments restants des itérables plus longs. En revanche, itertools.zip_longest() continue jusqu'à ce que l'itérable le plus long soit épuisé, en remplissant les valeurs manquantes avec une valeur par défaut (par défaut None, mais vous pouvez spécifier une autre valeur avec le paramètre fillvalue).

 

Question

Pourquoi zip() retourne-t-il un itérateur et non une liste ?

La fonction zip() retourne un itérateur pour des raisons d'efficacité mémoire. Avec un itérateur, les tuples sont générés à la demande (lazy evaluation), ce qui est particulièrement important lorsque vous travaillez avec de grands ensembles de données. Si vous avez besoin d'une liste, vous pouvez simplement utiliser list(zip(...)).

 

Question

Peut-on utiliser zip() avec plus de deux itérables ?

Absolument ! La fonction zip() accepte un nombre illimité d'itérables. Par exemple, zip(liste1, liste2, liste3, liste4) produira des tuples de 4 éléments, chacun provenant de l'itérable correspondant. Cela est très utile lorsque vous devez traiter des données provenant de multiples sources en parallèle.

 

Question

Comment apprendre à maîtriser zip() et les autres fonctions Python ?

Pour maîtriser zip() et l'ensemble des fonctions natives de Python, la pratique régulière est essentielle. Nous vous recommandons de suivre notre formation Python sur Believemy, qui couvre en profondeur toutes les fonctions essentielles du langage, avec des exercices pratiques et des projets concrets pour consolider vos connaissances.

Termes connexes

Découvrez notre glossaire Python

Parcourez les termes et définitions les plus couramment utilisés dans le domaine du développement avec Python.

Partager cet article

Tu veux nous aider ? Fais un lien vers cet article sur tes réseaux ou encore mieux : sur ton site, dans un article ou dans ta newsletter.