mi lista es:manera más Pythonic (y eficiente) de anidar una lista de pares
mylist=[1,2,3,4,5,6]
me gustaría convertir milista en una lista de pares:
[[1,2],[3,4],[5,6]]
¿Hay un Pythonic forma de hacerlo? ¿Comprensión de lista? Itertools?
mi lista es:manera más Pythonic (y eficiente) de anidar una lista de pares
mylist=[1,2,3,4,5,6]
me gustaría convertir milista en una lista de pares:
[[1,2],[3,4],[5,6]]
¿Hay un Pythonic forma de hacerlo? ¿Comprensión de lista? Itertools?
[mylist[2*n:2*n+2] for n in xrange(len(mylist)/2)]
Esta solución combina el uso de listas por comprensión y el corte en lonchas para extraer pares en la secuencia de la lista original, y construir una lista de las rebanadas.
Alternativamente, [mylist[n:n+2] for n in xrange(0, len(mylist), 2)]
que es lo mismo excepto xrange
cuentas de dos en lugar de las rebanadas. Gracias a Steven Rumbalski por la sugerencia.
Y ahora algo completamente diferente: aquí es una solución de (ab) uso de zip
y una función efímera en lugar de las cesiones intermedias:
>>> (lambda i: zip(i, i))(iter(mylist))
[(1, 2), (3, 4), (5, 6)]
yeppers, lista por comprensión es mi manera habitual de hacerlo:
>>> groupsize = 2
>>> [mylist[x:x+groupsize] for x in range(0,len(mylist),groupsize)]
[[1,2],[3,4],[5,6]]
>>> groupsize = 3
>>> [mylist[x:x+groupsize] for x in range(0,len(mylist),groupsize)]
[[1,2,3],[4,5,6]]
utilizo range
para la portabilidad, si está utilizando Python 2 (probablemente son) cambiar el range
a xrange
para ahorrar memoria.
Una forma alternativa:
zip(mylist[:-1:2], mylist[1::2])
que proporcione una lista de tuplas:
>>> zip(mylist[:-1:2],mylist[1::2])
[(1, 2), (3, 4), (5, 6)]
Si realmente desea una lista de listas:
map(list, zip(mylist[:-1:2],mylist[1::2]))
Salida del "mero "receta del itertools documentation:
def grouper(n, iterable, fillvalue=None):
"Collect data into fixed-length chunks or blocks"
# grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx
args = [iter(iterable)] * n
return izip_longest(fillvalue=fillvalue, *args)
-1. Esto dará 5 pares en una secuencia de 6 elementos, lo cual es incorrecto. Si quieres una receta itertools, debe ser 'mero'. –
Tiene toda la razón. Solucionado como se sugirió. –
Mi técnica preferida:
>>> mylist = [1, 2, 3, 4, 5, 6]
>>> mylist = iter(mylist)
>>> zip(mylist, mylist)
[(1, 2), (3, 4), (5, 6)]
que suelen utilizar los generadores en lugar de las listas de todos modos, por lo que la línea 2 no suele ser necesario.
Para mayor diversión, cambie el zip a 'zip (* [mylist] * groupsize)' para permitir el tamaño genérico del grupo. Por supuesto, el zip siempre va a tener un problema con el manejo de listas que tienen una longitud que no es divisible por el tamaño de grupo deseado. – Josiah
Esta parece ser la forma "más pitonica" de hacer esto. –
@ BrianM.Hunt No sé si estaría de acuerdo con eso. El zen de python dice "Simple es mejor que complejo", y si no entiendes exactamente cómo funcionan el zip y los iteradores, difícilmente podría llamarse simple. Sin embargo, es ciertamente la manera más inteligente. – Josiah
Más complicado de lo que necesita ser, simplemente coloque 'xrange' en 2 y la mayoría de las matemáticas desaparecerán. –
Comentarios incorporados. – wberry