2010-03-09 18 views
181

¿Cuál es el enfoque Pythonic para lograr lo siguiente?¿Cómo combinar listas en una lista de tuplas?

# Original lists: 

list_a = [1, 2, 3, 4] 
list_b = [5, 6, 7, 8] 

# List of tuples from 'list_a' and 'list_b': 

list_c = [(1,5), (2,6), (3,7), (4,8)] 

Cada miembro de list_c es una tupla, cuyo primer miembro es de list_a y el segundo es de list_b.

Respuesta

258
>>> list_a = [1, 2, 3, 4] 
>>> list_b = [5, 6, 7, 8] 
>>> zip(list_a, list_b) 
[(1, 5), (2, 6), (3, 7), (4, 8)] 
+56

usted tiene que saber que la función zip se detiene al final de la lista más corta, que puede no ser siempre lo que quiere . el módulo 'itertools' define un método' zip_longest() 'que se detiene al final de la lista más larga, completando los valores perdidos con algo que proporcione como parámetro. –

+5

@Adrien: aplausos por su comentario correspondiente. Para Python 2.x, 's/zip_longest()/izip_longest()'. Renombrado en Python 3.x a 'zip_longest()'. – bernie

+0

¿podría crear [(1,5), (1,6), (1,7), (1,8), (2,5), (2,6), etc. usando el comando zip? –

87

En python 3.0 zip devuelve un objeto zip. Puede obtener una lista llamando al list(zip(a, b)).

3

Sé que esta es una pregunta antigua y ya fue respondida, pero por alguna razón, todavía quiero publicar esta solución alternativa. Sé que es fácil averiguar qué función incorporada hace la "magia" que necesita, pero no está de más saber que puede hacerlo usted mismo.

>>> list_1 = ['Ace', 'King'] 
>>> list_2 = ['Spades', 'Clubs', 'Diamonds'] 
>>> deck = [] 
>>> for i in range(max((len(list_1),len(list_2)))): 
     while True: 
      try: 
       card = (list_1[i],list_2[i]) 
      except IndexError: 
       if len(list_1)>len(list_2): 
        list_2.append('') 
        card = (list_1[i],list_2[i]) 
       elif len(list_1)<len(list_2): 
        list_1.append('') 
        card = (list_1[i], list_2[i]) 
       continue 
      deck.append(card) 
      break 
>>> 
>>> #and the result should be: 
>>> print deck 
>>> [('Ace', 'Spades'), ('King', 'Clubs'), ('', 'Diamonds')] 
+2

Cambiar una de las listas de entrada (si difieren en longitud) no es un buen efecto secundario. Además, las dos asignaciones a 'card' en' if-elif' no son necesarias, es por eso que tienes 'continue'. (De hecho, sin 'continuar 'no tendría que cambiar las listas: ambas asignaciones mencionadas anteriormente deberían mantenerse y convertirse en' card = (list_1 [i],' ') 'y' card = (' ', list_2 [1]) 'respectivamente.) –

6

Puede utilizar un mapa lambda

a = [2,3,4] 
b = [5,6,7] 
c = map(lambda x,y:(x,y),a,b) 

Esto también funciona si no longitudes de las listas originales no coinciden

+1

¿Por qué usar una lambda? 'map (None, a, b)' –

+0

Ninguno lanzará un error ya que no se puede llamar. –

+0

¿Lo has intentado? –

4

La salida que habéis mostrado en la exposición del problema no es la tupla pero la lista

list_c = [(1,5), (2,6), (3,7), (4,8)] 

cheque por

type(list_c) 

teniendo en cuenta que quieren el resultado como tupla de list_a y list_b, hacer

tuple(zip(list_a,list_b)) 
+0

Desde mi punto de vista, parece ser lo que estoy buscando y funciona bien para ambos (lista y tupla). Porque cuando usas ** print **, verás el valor correcto (como se esperaba y mencionó @cyborg y @Lodewijk) y nada relacionado con el ** objeto ** como: '' o ''.Al menos, la solución sobre ** map ** y ** zip ** (solo) parece ser incompleta (o demasiado complicada) para mí. –

Cuestiones relacionadas