Python >> Tutoriel Python >  >> Python

Zip avec une sortie de liste au lieu de Tuple | La manière la plus pythonique

Réponse courte :Par défaut, le zip() La fonction renvoie un objet zip de tuples. Pour obtenir une liste de listes en sortie, utilisez la déclaration de compréhension de liste [list(x) for x in zip(l1, l2)] qui convertit chaque tuple en une liste et stocke les listes converties dans un nouvel objet de liste imbriqué.

Les codeurs Python intermédiaires connaissent le zip() fonction. Mais si vous êtes comme moi, vous avez souvent maudit la sortie de la fonction zip :tout d'abord, c'est un objet zip (et non une liste), et, deuxièmement, les éléments zippés individuels sont des tuples. Mais que se passe-t-il si vous avez besoin d'une liste de listes en sortie ? Cet article vous montrera la manière la plus Pythonique de le faire.

Problème :Soit un nombre de listes l1, l2, ... . Comment compresser les ièmes éléments de ces listes ensemble et obtenir une liste de listes ?

Exemple :Étant donné deux listes [1, 2, 3, 4] et ['Alice', 'Bob', 'Ann', 'Liz'] et vous voulez la liste des listes [[1, 'Alice'], [2, 'Bob'], [3, 'Ann'], [4, 'Liz']] .

l1 = [1, 2, 3, 4]
l2 = ['Alice', 'Bob', 'Ann', 'Liz']
# ... calculate result ...
# Output: [[1, 'Alice'], [2, 'Bob'], [3, 'Ann'], [4, 'Liz']]

Voici un bref aperçu de nos solutions :

Exercice :Créer une nouvelle liste l3 et modifiez les quatre méthodes pour compresser les trois listes (au lieu de seulement deux).

Méthode 1 :Expression du générateur

La première méthode utilise une expression de générateur et convertit l'itérable résultant en une liste en utilisant le list() constructeur.

l1 = [1, 2, 3, 4]
l2 = ['Alice', 'Bob', 'Ann', 'Liz']

# Method 1
zipped = list(list(x) for x in zip(l1, l2))

print(zipped)
# [[1, 'Alice'], [2, 'Bob'], [3, 'Ann'], [4, 'Liz']]

C'est efficace mais pas le moyen le plus concis d'accomplir cette tâche.

Méthode 2 :Compréhension de la liste

Une meilleure façon est d'utiliser la compréhension de liste qui est comme une expression de générateur mais qui crée une liste directement sans avoir besoin de convertir un itérable en liste (comme dans la méthode 1).

l1 = [1, 2, 3, 4]
l2 = ['Alice', 'Bob', 'Ann', 'Liz']

# Method 2:
zipped = [list(x) for x in zip(l1, l2)]

print(zipped)
# [[1, 'Alice'], [2, 'Bob'], [3, 'Ann'], [4, 'Liz']]

Méthode 3 :Pour Boucle et Zip

Les codeurs qui n'aiment pas la compréhension des listes et les expressions génératrices (ou qui ne comprennent pas ces belles fonctionnalités Python) utilisent souvent une simple boucle for. Dans le corps de la boucle, vous convertissez chaque tuple de l'objet zip en une liste et ajoutez cette liste à la liste imbriquée zipped .

l1 = [1, 2, 3, 4]
l2 = ['Alice', 'Bob', 'Ann', 'Liz']

# Method 3:
zipped = []
for t in zip(l1, l2):
    zipped.append(list(t))

print(zipped)
# [[1, 'Alice'], [2, 'Bob'], [3, 'Ann'], [4, 'Liz']]

Cette méthode est lisible mais moins concise.

Méthode 4 :boucle For et indexation

Cette méthode est souvent utilisée par les codeurs qui ne connaissent ni le zip() méthode, ni compréhension de liste, ni expressions génératrices :bouclez sur tous les indices et ajoutez une nouvelle liste obtenue en regroupant les ièmes éléments de la liste.

l1 = [1, 2, 3, 4]
l2 = ['Alice', 'Bob', 'Ann', 'Liz']

# Method 4:
zipped = []
for i in range(len(l1)):
    zipped.append([l1[i], l2[i]])

print(zipped)
# [[1, 'Alice'], [2, 'Bob'], [3, 'Ann'], [4, 'Liz']]

Cependant, cette méthode est la moins pythonique, longue et ne fonctionne que pour des listes de taille égale.

Exercice :Que se passe-t-il si la première liste contient plus d'éléments que la seconde ?

Méthode 5 :Zip() + Map() + List()

Une manière fonctionnelle de résoudre ce problème est la fonction map() qui applique une fonction à chaque élément d'un itérable et renvoie un objet map. Vous pouvez passer le list() constructeur au map() pour convertir chaque tuple de l'objet zip en une liste. Vous pouvez ensuite convertir l'objet cartographique en liste.

l1 = [1, 2, 3, 4]
l2 = ['Alice', 'Bob', 'Ann', 'Liz']

# Method 5
print(list(map(list,zip(l1, l2))))
# [[1, 'Alice'], [2, 'Bob'], [3, 'Ann'], [4, 'Liz']]

Je ne recommande pas cette méthode car la programmation fonctionnelle peut être difficile à comprendre pour de nombreux codeurs débutants. Guido van Rossum, le créateur de Python, n'aimait pas non plus la programmation fonctionnelle.

Discussion

La façon la plus Pythonique de créer une liste de listes en comprimant plusieurs listes est la déclaration de compréhension de liste [list(x) for x in zip(l1, l2)] . La compréhension des listes est rapide, efficace, concise et lisible. Vous pouvez également l'étendre au cas général en ajoutant plus de listes à la fonction zip :[list(x) for x in zip(l1, l2, l3, ..., ln)] . Le zip() La fonction est également robuste contre des listes de longueurs différentes. Dans ce cas, les éléments jusqu'à l'index maximal de la liste la plus courte sont compressés.