2011-05-01 70 views
71

Soy bastante nuevo en python (un par de semanas) y me he encontrado con un problema para unirme a una lista. Ahora, sé que una lista se pueden unir para hacer una cadena larga como en:Unir pares de elementos de una lista - Python

x = ['a', 'b', 'c', 'd'] 
print ''.join(x) 

Obviamente, esto seria:

'abcd' 

Sin embargo, lo que yo estoy tratando de hacer es simplemente unirse a la primera y segundas cadenas en la lista, luego únete al tercero y cuarto, y así sucesivamente. En resumen, en el ejemplo anterior, en cambio, obtenga una salida de:

['ab', 'cd'] 

¿Hay alguna manera sencilla de hacerlo? Probablemente también debería mencionar que las longitudes de las cadenas en la lista serán impredecibles, al igual que el número de cadenas dentro de la lista, aunque el número de cadenas siempre será par. Así que la lista original podría ser:

['abcd', 'e', 'fg', 'hijklmn', 'opq', 'r'] 

o lo que sea. De todos modos, cualquier ayuda sería muy apreciada, así que gracias de antemano.

+0

* “Probablemente debería también mencionar que las longitudes de las cadenas de la lista será impredecible "* - Entonces, ¿importa la duración? Es decir. ¿Desea unirse a cada par de elementos de la lista, o desea ver el contenido y unirse siempre que el elemento resultante se mantenga por debajo de algún límite de longitud especial? – poke

+0

simplemente únete a cada par, solo pensé que no saber el número de pares podría ser un problema – John

Respuesta

66

Puede utilizar la notación de rebanada con pasos:

>>> x = "abcdefghijklm" 
>>> x[0::2] #0. 2. 4... 
'acegikm' 
>>> x[1::2] #1. 3. 5 .. 
'bdfhjl' 
>>> [i+j for i,j in zip(x[::2], x[1::2])] # zip makes (0,1),(2,3) ... 
['ab', 'cd', 'ef', 'gh', 'ij', 'kl'] 

misma lógica se aplica para las listas también. La longitud de la cuerda no importa, porque simplemente estás agregando dos cuerdas.

+1

No hay duda de que la respuesta de kevpie es mucho mejor. En este caso, '' x [::: 2] '' crea un objeto, '' x [1 :: 2] '' crea otro objeto, estas creaciones se basan probablemente en el cálculo de índices debajo del capó y una llamada a una función con estos dos objetos pasados ​​como argumentos es necesario antes de poder obtener los sucesivos pares de elementos que deben concatenarse. Mientras que en la respuesta de kevpie, solo existe la creación de un iterador y luego la iteración se salta de un elemento a otro de la lista intacta sin tener que cuidar los índices, y eso es mucho más pitónico. – eyquem

+0

@eyquem, utilizando 'itertools.islice' en lugar de [], elimina los objetos intermedios. Pero como ambas respuestas funcionan en las mismas condiciones y las devuelve, ambas tienen razón. Y 'zip (i [:: 2], i [1 :: 2])' parece tan dulce para mí, entonces, ¿por qué no? :) – utdemir

1
>>> lst = ['abcd', 'e', 'fg', 'hijklmn', 'opq', 'r'] 
>>> print [lst[2*i]+lst[2*i+1] for i in range(len(lst)/2)] 
['abcde', 'fghijklmn', 'opqr'] 
2

Sin la creación de listas provisionales:

>>> import itertools 
>>> s = 'abcdefgh' 
>>> si = iter(s) 
>>> [''.join(each) for each in itertools.izip(si, si)] 
['ab', 'cd', 'ef', 'gh'] 

o:

>>> import itertools 
>>> s = 'abcdefgh' 
>>> si = iter(s) 
>>> map(''.join, itertools.izip(si, si)) 
['ab', 'cd', 'ef', 'gh'] 
+0

Agradable, pero teniendo en cuenta que mi código me deja comenzando con la lista original de todos modos, creo que no estoy de acuerdo con utdmr's ... gracias aunque – John

25

utilizar un iterador.

Lista de comprensión:

>>> si = iter(['abcd', 'e', 'fg', 'hijklmn', 'opq', 'r']) 
>>> [c+next(si, '') for c in si] 
['abcde', 'fghijklmn', 'opqr'] 
  • muy eficiente para el uso de memoria.
  • Exactamente un recorrido de s

expresión Generador:

>>> si = iter(['abcd', 'e', 'fg', 'hijklmn', 'opq', 'r']) 
>>> pair_iter = (c+next(si, '') for c in si) 
>>> pair_iter # can be used in a for loop 
<generator object at 0x4ccaa8> 
>>> list(pair_iter) 
['abcde', 'fghijklmn', 'opqr'] 
  • uso como un iterador

Uso de mapa, str .__ add__, iter

>>> si = iter(['abcd', 'e', 'fg', 'hijklmn', 'opq', 'r']) 
>>> map(str.__add__, si, si) 
['abcde', 'fghijklmn', 'opqr'] 

next(iterator[, default]) comenzando en Python 2.6

+2

De lejos, la mejor respuesta. Ver mi comentario a la respuesta de utdemir. – eyquem

1

Bueno, yo lo haría de esta manera como yo no soy bueno con Regs ..

CÓDIGO

t = '1. eat, food\n\ 
7am\n\ 
2. brush, teeth\n\ 
8am\n\ 
3. crack, eggs\n\ 
1pm'.splitlines() 

print [i+j for i,j in zip(t[::2],t[1::2])] 

de salida:

['1. eat, food 7am', '2. brush, teeth 8am', '3. crack, eggs 1pm'] 

Espero que esto ayude :)

4

sólo para estar :-) Pythonic

>>> x = ['a1sd','23df','aaa','ccc','rrrr', 'ssss', 'e', ''] 
>>> [x[i] + x[i+1] for i in range(0,len(x),2)] 
['a1sd23df', 'aaaccc', 'rrrrssss', 'e'] 

en caso de que el que desea se alarme si la longitud de la lista es extraño que puede probar:

[x[i] + x[i+1] if not len(x) %2 else 'odd index' for i in range(0,len(x),2)] 

mejor de la suerte

Cuestiones relacionadas