2009-07-31 37 views
11

Específicamente, tengo dos listas de cadenas que me gustaría para combinar en una cadena, donde cada línea es los próximos dos cadenas de las listas, separados por espacios:¿Cómo puedo iterar sobre las tuplas de los elementos de dos o más listas en Python?

a = ['foo1', 'foo2', 'foo3'] 
b = ['bar1', 'bar2', 'bar3'] 

Quiero una función combine_to_lines() que volvería:

"""foo1 bar1 
foo2 bar2 
foo3 bar3""" 

admito que ya he solucionado este problema, así que voy a publicar la respuesta. Pero tal vez alguien más tenga una mejor o vea un defecto en la mía.

Actualización: Sobre simplifiqué mi ejemplo anterior. En mi problema del mundo real, las líneas se formatearon de una manera más complicada que requería que las tuplas devueltas desde zip() se desempaquetaran. Pero felicitaciones a mhawke por llegar a la solución más simple para este ejemplo.

Respuesta

14

No es necesario que deshacer y rehacer las tuplas devueltas por postal:

'\n'.join(' '.join(x) for x in zip(a, b)) 
1

¿Preguntas sobre la función zip?

+1

Sí. No podía recordarlo, y una búsqueda en Google tomó un poco de tiempo para refrescar mi memoria. Quizás esta pregunta surja en búsquedas futuras. –

+0

sí, y ayudó a trotar mi memoria. Así que gracias. – aeroNotAuto

+0

Otra pregunta como la respuesta a la pregunta? :) –

9

"zip function" devuelve una lista de tuplas, donde la i-ésima tupla contiene el elemento i-ésimo de cada una de las secuencias de argumento o iterables. "

def combine_to_lines(list1, list2): 
    return '\n'.join([' '.join((a, b)) for a, b in zip(list1, list2)]) 
7
>>> a = ['foo1', 'foo2', 'foo3'] 
>>> b = ['bar1', 'bar2', 'bar3'] 
>>> for i in zip(a,b): 
... print ' '.join(i) 
... 
foo1 bar1 
foo2 bar2 
foo3 bar3 
0

Aquí hay una sola línea. Podría hacer x + ' ' + y si estuviera tan inclinado, no estoy seguro si sería más lento o no.

>>> a = ['foo1', 'foo2' , 'foo3'] 
>>> b = ['bar1', 'bar2', 'bar3'] 
>>> '\n'.join(' '.join([x,y]) for (x,y) in zip(a,b)) 
'foo1 bar1\nfoo2 bar2\nfoo3 bar3' 
>>> print _ 
foo1 bar1 
foo2 bar2 
foo3 bar3 
0
'\n'.join(((str(x) + ' ' + str(y)) for (x, y) in zip(a, b))) 
0

simple como:

+0

¿dónde están las nuevas líneas? – mhawke

1

Comprendo que esto es una pregunta muy antigua, pero es interesante observar que esto se puede ver como matrix transposition.

>>> import numpy 
>>> data = numpy.array([['foo1','foo2','foo3'],['bar1','bar2','bar3']]) 
>>> print(data) 
[['foo1' 'foo2' 'foo3'] 
['bar1' 'bar2' 'bar3']] 
>>> print(data.transpose()) 
[['foo1' 'bar1'] 
['foo2' 'bar2'] 
['foo3' 'bar3']] 

Si se trata de un conjunto de datos grande o más listas, esta podría ser una solución más eficiente.

0

En 3.x pitón:

'\n'.join(' '.join(x) for x in zip(a, b)) 

postal devuelve una lista de tuplas. la cremallera se detiene cuando el más corto de aob se detiene.

en Python 2.x:

si itertools.izip detendría cuando una de las listas se quedó sin elementos, pero itertools.izip_longest se detendrá hasta que las listas no tienen ningún elemento más

import itertools 
'\n'.join(' '.join(x) for x in itertools.izip(a, b)) 

'\n'.join(' '.join(x) for x in itertools.izip_longest(a, b)) 
+0

también acredita a mhawke por encontrar la solución principal –

+0

¿Por qué escribes "In Python 3.x" arriba? Acabo de confirmar que el cierre se detiene cuando el más corto de aob se detiene en Python 2.7.5. –

+0

¡tienes razón! por lo que entiendo, esto no era una característica en Python 2.x antes y fue portado desde 3.x estoy en lo cierto? en caso afirmativo, ¿de qué versión fui actualizado? –

Cuestiones relacionadas