Listes Zip en Python

151

J'essaye d'apprendre comment «compresser» des listes. À cette fin, j'ai un programme, où à un moment donné, je fais ce qui suit:

x1, x2, x3 = stuff.calculations(withdataa)

Cela me donne trois listes, x1, x2et x3, chacun, par exemple, la taille 20.

Maintenant oui:

zipall = zip(x1, x2, x3)

Cependant, quand je fais:

print "len of zipall %s" % len(zipall)

J'en ai 20, ce qui n'est pas ce à quoi je m'attendais. J'en attendais trois. Je pense que je fais quelque chose de fondamentalement mal.

AJW
la source
4
Qu'espérez-vous zipfaire exactement ? Pourquoi devriez-vous avoir trois listes - à quoi ressembleraient-elles?
Daniel Roseman
zip renvoie une liste de tuples.
Démo du

Réponses:

225

Lorsque vous zip()regroupez trois listes contenant chacune 20 éléments, le résultat a vingt éléments. Chaque élément est un triplet.

Voir par vous-même:

In [1]: a = b = c = range(20)

In [2]: zip(a, b, c)
Out[2]: 
[(0, 0, 0),
 (1, 1, 1),
 ...
 (17, 17, 17),
 (18, 18, 18),
 (19, 19, 19)]

Pour savoir combien d'éléments chaque tuple contient, vous pouvez examiner la longueur du premier élément:

In [3]: result = zip(a, b, c)

In [4]: len(result[0])
Out[4]: 3

Bien sûr, cela ne fonctionnera pas si les listes étaient vides au départ.

NPE
la source
1
len (result [0]) ne fonctionnera pas. L'objet 'zip' n'est pas en indice
GilbertS
2
@GilbertS dans Python 2 a ziprenvoyé une liste. Dans Python 3 c'est un itérateur
Tomerikoo
63

zip prend un tas de listes de likes

a: a1 a2 a3 a4 a5 a6 a7...
b: b1 b2 b3 b4 b5 b6 b7...
c: c1 c2 c3 c4 c5 c6 c7...

et les "zips" dans une liste dont les entrées sont 3-tuples (ai, bi, ci). Imaginez dessiner une fermeture à glissière horizontalement de gauche à droite.

Katriel
la source
@Sigur: "Convertir le tuple en liste et
David Cary
36

En Python 2.7, cela aurait pu fonctionner correctement:

>>> a = b = c = range(20)
>>> zip(a, b, c)

Mais dans Python 3.4, cela devrait être (sinon, le résultat sera quelque chose comme <zip object at 0x00000256124E7DC8>):

>>> a = b = c = range(20)
>>> list(zip(a, b, c))
Ajay
la source
28

zip crée une nouvelle liste, remplie de tuples contenant des éléments des arguments itérables:

>>> zip ([1,2],[3,4])
[(1,3), (2,4)]

J'attends ce que vous essayez de créer un tuple où chaque élément est une liste.

Conteur - Unslander Monica
la source
14

Source: Mon article de blog (meilleur formatage)

Exemple

numbers = [1,2,3]
letters = 'abcd'

zip(numbers, letters)
# [(1, 'a'), (2, 'b'), (3, 'c')]

Contribution

Zéro ou plusieurs itérables [1] (ex. Liste, chaîne, tuple, dictionnaire)

Sortie (liste)

1er tuple = (élément_1 des nombres, élément_1 des lettres)

2ème tuple = (nombres e_2, lettres e_2)

n-ième tuple = (e_n nombres, e_n lettres)

  1. Liste de n tuples: n est la longueur de l'argument le plus court (entrée)
    • len (nombres) == 3 <len (lettres) == 4 → court = 3 → retourne 3 tuples
  2. Length each tuple = # of args (tuple prend un élément de chaque arg)
    • args = (nombres, lettres); len (args) == 2 → tuple avec 2 éléments
  3. ith tuple = (element_i arg1, element_i arg2…, element_i arg n)

Cas de bord

1) Chaîne vide: len (str) = 0 = pas de tuples

2) Chaîne unique: len (str) == 2 tuples avec len (args) == 1 élément (s)

zip()
# []
zip('')
# []
zip('hi')
# [('h',), ('i',)]

Zip en action!

1. Construisez un dictionnaire [2] à partir de deux listes

keys = ["drink","band","food"]
values = ["La Croix", "Daft Punk", "Sushi"]

my_favorite = dict( zip(keys, values) )

my_favorite["drink"]
# 'La Croix'

my_faves = dict()
for i in range(len(keys)):
    my_faves[keys[i]] = values[i]
  • zip est une solution élégante, claire et concise

2. Imprimer des colonnes dans un tableau

"*" [3] est appelé "déballage": f(*[arg1,arg2,arg3]) == f(arg1, arg2, arg3)

student_grades = [
[   'Morty'  ,  1   ,  "B"  ],
[   'Rick'   ,  4   ,  "A"  ],
[   'Jerry'  ,  3   ,  "M"  ],
[  'Kramer'  ,  0   ,  "F"  ],
]

row_1 = student_grades[0]
print row_1
# ['Morty', 1, 'B']

columns = zip(*student_grades)
names = columns[0]
print names
# ('Morty', 'Rick', 'Jerry', 'Kramer')

Crédit supplémentaire: décompression

zip(*args) est appelé «décompression» car il a pour effet inverse zip

numbers = (1,2,3)
letters = ('a','b','c')

zipped = zip(numbers, letters)
print zipped
# [(1, 'a'), (2, 'b'), (3, 'c')]

unzipped = zip(*zipped)
print unzipped
# [(1, 2, 3), ('a', 'b', 'c')]
  • unzipped: tuple_1 = e1 de chaque tuple compressé. tuple_2 = e2 de chaquezipped

Notes de bas de page

  1. Un objet capable de renvoyer ses membres un par un (ex. List [1,2,3], string 'I like codin', tuple (1,2,3), dictionary {'a': 1, 'b' : 2})
  2. {clé1: valeur1, clé2: valeur2 ...}
  3. «Déballage» (*)

* Code:

# foo - function, returns sum of two arguments
def foo(x,y):
    return x + y
print foo(3,4)
# 7

numbers = [1,2]
print foo(numbers)
# TypeError: foo() takes exactly 2 arguments (1 given)

print foo(*numbers)
# 3

*a pris numbers(1 argument) et a «déballé» ses 2 éléments en 2 arguments

JBallin
la source
14

Fondamentalement, la fonction zip fonctionne sur les listes, les tuples et les dictionnaires en Python. Si vous utilisez IPython, tapez simplement zip? Et vérifiez en quoi consiste zip ().

Si vous n'utilisez pas IPython, installez-le simplement: "pip install ipython"

Pour les listes

a = ['a', 'b', 'c']
b = ['p', 'q', 'r']
zip(a, b)

La sortie est [('a', 'p'), ('b', 'q'), ('c', 'r')

Pour le dictionnaire:

c = {'gaurav':'waghs', 'nilesh':'kashid', 'ramesh':'sawant', 'anu':'raje'}
d = {'amit':'wagh', 'swapnil':'dalavi', 'anish':'mane', 'raghu':'rokda'}
zip(c, d)

La sortie est:

[('gaurav', 'amit'),
 ('nilesh', 'swapnil'),
 ('ramesh', 'anish'),
 ('anu', 'raghu')]
Wagh
la source
1
zip (c, d) joue zip (list (c), list (d))
Stephen Woodbridge
13

En Python 3 zip renvoie un itérateur à la place et doit être passé à une fonction de liste pour obtenir les tuples compressés:

x = [1, 2, 3]; y = ['a','b','c']
z = zip(x, y)
z = list(z)
print(z)
>>> [(1, 'a'), (2, 'b'), (3, 'c')]

Ensuite unzip, il suffit de conjuguer l'itérateur zippé:

x_back, y_back = zip(*z)
print(x_back); print(y_back)
>>> (1, 2, 3)
>>> ('a', 'b', 'c')

Si la forme originale de la liste est nécessaire au lieu des tuples:

x_back, y_back = zip(*z)
print(list(x_back)); print(list(y_back))
>>> [1,2,3]
>>> ['a','b','c']
Shivid
la source
1
La balise question indique Python 2.7; c'est pour Python 3. D'ailleurs, cette réponse le mentionne déjà.
0 0
8

Par souci d'exhaustivité.

Lorsque les longueurs des listes compressées ne sont pas égales. La longueur de la liste de résultats deviendra la plus courte sans qu'aucune erreur ne se soit produite

>>> a = [1]
>>> b = ["2", 3]
>>> zip(a,b)
[(1, '2')]
transang
la source
1

Je ne pense pas que ziprenvoie une liste. ziprenvoie un générateur. Vous devez faire list(zip(a, b))pour obtenir une liste de tuples.

x = [1, 2, 3]
y = [4, 5, 6]
zipped = zip(x, y)
list(zipped)
Ankur Kothari
la source
1
La balise question indique Python 2.7; c'est pour Python 3. D'ailleurs, cette réponse le mentionne déjà.
0 0
1

Cela vaut la peine d'ajouter ici car c'est une question très bien classée sur zip. zipest génial, Python idiomatique - mais il ne s'adapte pas très bien du tout aux grandes listes.

Au lieu de:

books = ['AAAAAAA', 'BAAAAAAA', ... , 'ZZZZZZZ']
words = [345, 567, ... , 672]

for book, word in zip(books, words):
   print('{}: {}'.format(book, word))

Utilisez izip. Pour le traitement moderne, il le stocke dans la mémoire cache L1 et est beaucoup plus performant pour les listes plus grandes. Utilisez-le aussi simplement que d'ajouter un i:

for book, word in izip(books, words):
   print('{}: {}'.format(book, word))
Micheal J. Roberts
la source