¿Cuál es la mejor manera de dividir una lista en partes más o menos iguales? Por ejemplo, si la lista tiene 7 elementos y se divide en 2 partes, queremos obtener 3 elementos en una parte, y la otra debe tener 4 elementos.
Busco algo así como even_split(L, n)
que las interrupciones L
enn
partes.
def chunks(L, n):
""" Yield successive n-sized chunks from L.
"""
for i in range(0, len(L), n):
yield L[i:i+n]
El código anterior proporciona fragmentos de 3, en lugar de 3 fragmentos. Simplemente podría transponer (iterar sobre esto y tomar el primer elemento de cada columna, llamar a esa parte uno, luego tomar el segundo y ponerlo en la parte dos, etc.), pero eso destruye el orden de los elementos.
>>> chunkIt(range(8), 6)
=>[[0], [1], [2, 3], [4], [5], [6], [7]]
chunkIt(range(10), 9)
debería devolver 9 partes, pero no lo hace.Puede escribirlo simplemente como un generador de listas:
Ejemplo:
fuente
n = min(n, len(a)) # don't create empty buckets
en la línea 1 para evitar crear cubos vacíos en escenarios comolist(split(range(X, Y)))
dondeX < Y
Esta es la razón de ser de
numpy.array_split
*:* crédito a Zero Piraeus en la habitación 6
fuente
*
deprint
para?print(L)
e `print (* L). Consulte también stackoverflow.com/a/36908/2184122 o busque "uso de asterisco en Python".Mientras no quieras nada tonto como trozos continuos:
fuente
zip(*chunkify(range(13), 3))
resultados en[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11)]
Cambiar el código para producir
n
fragmentos en lugar de fragmentos den
:lo que da:
Esto asignará los elementos adicionales al grupo final que no es perfecto pero está dentro de su especificación de "aproximadamente N partes iguales" :-) Con eso, quiero decir que 56 elementos serían mejores como (19,19,18) mientras que esto da (18,18,20).
Puede obtener la salida más equilibrada con el siguiente código:
que salidas:
fuente
for x in chunks(mylist,num): print x
obtengo los fragmentos deseados, pero entre ellos obtengo una lista vacía. ¿Alguna idea de por qué? Es decir, obtengo muchos[]
, uno después de cada porción.Si divide los
n
elementos enk
partes aproximadas , puede hacer que lasn % k
partes sean 1 elemento más grande que las otras partes para distribuir los elementos adicionales.El siguiente código le dará la longitud de los fragmentos:
Ejemplo:
n=11, k=3
resultados en[4, 4, 3]
Luego puede calcular fácilmente los índices de inicio para los fragmentos:
Ejemplo:
n=11, k=3
resultados en[0, 4, 8]
Usando el
i+1
fragmento th como límite, obtenemos que eli
fragmento th de la listal
con lenn
esComo paso final, cree una lista de todos los fragmentos utilizando la comprensión de la lista:
Ejemplo:
n=11, k=3, l=range(n)
resultados en[range(0, 4), range(4, 8), range(8, 11)]
fuente
Esto hará la división por una sola expresión:
La lista en este ejemplo tiene el tamaño 18 y se divide en 5 partes. El tamaño de las partes difiere en no más de un elemento.
fuente
Ver
more_itertools.divide
:Instalar a través de
> pip install more_itertools
.fuente
Aquí hay uno que agrega
None
para hacer que las listas tengan la misma longitudfuente
Aquí está mi solución:
Produce
fuente
Aquí hay un generador que puede manejar cualquier número positivo (entero) de fragmentos. Si el número de fragmentos es mayor que la longitud de la lista de entrada, algunos fragmentos estarán vacíos. Este algoritmo alterna entre fragmentos cortos y largos en lugar de segregarlos.
También he incluido un código para probar la
ragged_chunks
función.Podemos hacer esto un poco más eficiente exportando la multiplicación a la
range
llamada, pero creo que la versión anterior es más legible (y SECA).fuente
Echa un vistazo a numpy.split :
fuente
Implementación usando el método numpy.linspace.
Simplemente especifique el número de partes en las que desea dividir la matriz. Las divisiones serán de un tamaño casi igual.
Ejemplo:
Da :
fuente
Mi solución, fácil de entender.
Y la frase más corta en esta página (escrita por mi chica)
fuente
Usando la comprensión de la lista:
fuente
Otra forma sería algo como esto, la idea aquí es usar el mero, pero deshacerse de él
None
. En este caso tendremos todas las 'partes_pequeñas' formadas a partir de elementos en la primera parte de la lista, y 'partes_más grandes' de la parte posterior de la lista. La longitud de las 'partes más grandes' es len (small_parts) + 1. Necesitamos considerar x como dos sub-partes diferentes.La forma en que lo configuré devuelve una lista de tuplas:
fuente
Aquí hay otra variante que distribuye los elementos "restantes" de manera uniforme entre todos los fragmentos, uno a la vez hasta que no quede ninguno. En esta implementación, los fragmentos más grandes se producen al comienzo del proceso.
Por ejemplo, genere 4 fragmentos de una lista de 14 elementos:
fuente
Lo mismo que la respuesta del trabajo , pero tiene en cuenta listas con un tamaño más pequeño que el número de fragmentos.
si n (número de fragmentos) es 7 y lst (la lista para dividir) es [1, 2, 3] los fragmentos son [[0], [1], [2]] en lugar de [[0], [1 ], [2], [], [], [], []]
fuente
También puedes usar:
fuente
Ejemplo:
l = [a for a in range(97)]
Debe constar de 10 partes, cada una con 9 elementos, excepto la última.Salida:
fuente
Supongamos que desea dividir una lista [1, 2, 3, 4, 5, 6, 7, 8] en 3 listas de elementos
como [[1,2,3], [4, 5, 6], [7, 8]] , donde si los últimos elementos restantes son inferiores a 3, se agrupan.
Salida: [[1,2,3], [4, 5, 6], [7, 8]]
Donde la longitud de una parte es 3. Reemplace 3 con su propio tamaño de trozo.
fuente
1>
2>
fuente
Aquí está mi versión (inspirada en la de Max)
fuente
Redondear el espacio de línea y usarlo como índice es una solución más fácil de lo que propone amit12690.
fuente
Elegido de este enlace , y esto fue lo que me ayudó. Tenía una lista predefinida.
fuente
Digamos que quiere dividir en 5 partes:
fuente
He escrito código en este caso yo mismo:
divide_ports (1, 10, 9) devolvería
fuente
este código funciona para mí (compatible con Python3):
ejemplo (para el tipo bytearray , pero también funciona para las listas ):
fuente
Este proporciona trozos de longitud <= n,> = 0
def
por ejemplo
fuente
Intenté la mayoría de las soluciones, pero no funcionaron para mi caso, así que creo una nueva función que funciona para la mayoría de los casos y para cualquier tipo de matriz:
fuente