Lista dividida en listas más pequeñas (divididas por la mitad)

150

Estoy buscando una manera de dividir fácilmente una lista de Python por la mitad.

Entonces, si tengo una matriz:

A = [0,1,2,3,4,5]

Yo podría obtener:

B = [0,1,2]

C = [3,4,5]
corymathews
fuente

Respuestas:

226
A = [1,2,3,4,5,6]
B = A[:len(A)//2]
C = A[len(A)//2:]

Si quieres una función:

def split_list(a_list):
    half = len(a_list)//2
    return a_list[:half], a_list[half:]

A = [1,2,3,4,5,6]
B, C = split_list(A)
Jason Coon
fuente
70
Debe forzar la división int en Python 3. // es obligatorio.
Stefan Kendall
44
Buena solución, gracias. También funciona con fracciones como 80/20 en Python3B = A[:(len(A) // 10) * 8] C = A[(len(A) // 10) * 8:]
Gergely M
87

Una solución un poco más genérica (puede especificar la cantidad de partes que desea, no solo dividir 'a la mitad'):

EDITAR : publicación actualizada para manejar longitudes de lista impares

EDIT2 : actualizar la publicación nuevamente según los comentarios informativos de Brians

def split_list(alist, wanted_parts=1):
    length = len(alist)
    return [ alist[i*length // wanted_parts: (i+1)*length // wanted_parts] 
             for i in range(wanted_parts) ]

A = [0,1,2,3,4,5,6,7,8,9]

print split_list(A, wanted_parts=1)
print split_list(A, wanted_parts=2)
print split_list(A, wanted_parts=8)
ChristopheD
fuente
2
Cuando la lista no se divide de manera uniforme (p. Ej., Split_list ([1,2,3], 2)), en realidad esto devolverá las listas wanted_parts + 1.
Brian el
3
Una mejor manera creo que sería: longitud = len (alist); return [alist [i * length // wanted_parts: (i + 1) * length // wanted_parts] para i en el rango (wanted_parts)]. De esa manera, obtienes una distribución lo más uniforme posible y siempre obtienes exactamente los elementos que se desean (partes iguales con [] si se desean partes> len (A))
Brian
2
hola .. que significa el símbolo "//" ??
frazman
2
@Fraz Se entiende como comentario en línea. Ignore "// wanted_parts" y "// wanted_parts" para que el script se ejecute.
PunjCoder
19
//significa división entera. No deben dejarse de lado ya que son bastante esenciales para que esto funcione.
Alphadelta14
43
f = lambda A, n=3: [A[i:i+n] for i in range(0, len(A), n)]
f(A)

n - la longitud predefinida de las matrices de resultados

Jaro
fuente
1
Esto funciona muy bien en mi situación, sin embargo, está agregando todos los últimos índices de cada lista en su propia lista. Difícil de explicar. Responda si puede ayudar y le explicaré más.
Mike Issa
34
def split(arr, size):
     arrs = []
     while len(arr) > size:
         pice = arr[:size]
         arrs.append(pice)
         arr   = arr[size:]
     arrs.append(arr)
     return arrs

Prueba:

x=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
print(split(x, 5))

resultado:

[[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13]]
Siamand
fuente
1
también es útil para convertir la lista a matriz
mpgn
Esto funciona, pero no del todo. Estoy usando esta función en un bucle, y las longitudes varían. En otras palabras: for i,j in zip(list,lengths): print(split(i,j)). Las listas listy lengthstienen la misma longitud. j es alternativo: 5,4,5,4,5, y la función de división funciona en las dos primeras alternancias, es decir, divide el primero ide la lista por 5 y 4, PERO en la siguiente iteración lo divide en 4,4, 1) : \ Responda si desea que le explique más (publique una nueva pregunta)
Mike Issa
15

Si no te importa el pedido ...

def split(list):  
    return list[::2], list[1::2]

list[::2]obtiene cada segundo elemento de la lista a partir del elemento 0.
list[1::2]obtiene cada segundo elemento de la lista a partir del primer elemento.

sentythee
fuente
44
Cuidadoso nombrar el argumento listcon sombrear el list(...)incorporado. Lo he visto lsty list_usado comúnmente para evitarlo.
Taylor Edmiston
3
esto se siente más pitónico (ignorando los nombres incorrectos)
Tjorriemorrie
12

B,C=A[:len(A)/2],A[len(A)/2:]

John Montgomery
fuente
Creo que olvidaste la división entre 2 pasos. :)
Stefan Kendall
11

Aquí hay una solución común, dividir arr en parte de conteo

def split(arr, count):
     return [arr[i::count] for i in range(count)]
Chris Song
fuente
Esto pierde el orden de la lista
Timmah
9
def splitter(A):
    B = A[0:len(A)//2]
    C = A[len(A)//2:]

 return (B,C)

Probé, y se requiere la doble barra para forzar la división int en python 3. Mi publicación original fue correcta, aunque wysiwyg se rompió en Opera, por alguna razón.

Stefan Kendall
fuente
no maneja len impar (A), ¿tiene solución para eso?
N997
6

Hay una receta oficial de Python para el caso más generalizado de dividir una matriz en matrices más pequeñas de tamaño n.

from itertools import izip_longest
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)

Este fragmento de código es de la página del documento de itertools de Python .

Jonathan Berger
fuente
6

Usando el corte de la lista . La sintaxis es básicamentemy_list[start_index:end_index]

>>> i = [0,1,2,3,4,5]
>>> i[:3] # same as i[0:3] - grabs from first to third index (0->2)
[0, 1, 2]
>>> i[3:] # same as i[3:len(i)] - grabs from fourth index to end
[3, 4, 5]

Para obtener la primera mitad de la lista, se divide desde el primer índice hasta len(i)//2(donde //está la división de enteros, entonces 3//2 will give the floored result of1 , instead of the invalid list index of1.5`):

>>> i[:len(i)//2]
[0, 1, 2]

..y el intercambio de los valores para obtener la segunda mitad:

>>> i[len(i)//2:]
[3, 4, 5]
dbr
fuente
¿Qué pasa con las listas impares de len?
N997
@ N997 El código aún debería funcionar; simplemente terminas con diferentes números de elementos en cada lista. Entonces, digamos que la lista tiene tres elementos, el operador de la división 3//2muestra el resultado 1, entonces da , entonces obtienes i[:1]cuál te da [0]y i[1:]qué da[1, 2]
dbr
3

Si tiene una lista grande, es mejor usar itertools y escribir una función para obtener cada parte según sea necesario:

from itertools import islice

def make_chunks(data, SIZE):
    it = iter(data)
    # use `xragne` if you are in python 2.7:
    for i in range(0, len(data), SIZE):
        yield [k for k in islice(it, SIZE)]

Puedes usar esto como:

A = [0, 1, 2, 3, 4, 5, 6]

size = len(A) // 2

for sample in make_chunks(A, size):
    print(sample)

El resultado es:

[0, 1, 2]
[3, 4, 5]
[6]

Gracias a @thefourtheye y @Bede Constantinides

MA Heshmat Khah
fuente
3

10 años después ... pensé, ¿por qué no agregar otro?

arr = 'Some random string' * 10; n = 4
print([arr[e:e+n] for e in range(0,len(arr),n)])
RoyM
fuente
2

Si bien las respuestas anteriores son más o menos correctas, puede tener problemas si el tamaño de su matriz no es divisible por 2, como resultado de que a / 2, siendo extraño, es flotante en Python 3.0, y en una versión anterior si especifique from __future__ import divisional comienzo de su script. En cualquier caso, es mejor optar por la división de enteros, es decir a // 2, para obtener compatibilidad "hacia adelante" de su código.

usuario91259
fuente
2

Esto es similar a otras soluciones, pero un poco más rápido.

# Usage: split_half([1,2,3,4,5]) Result: ([1, 2], [3, 4, 5])

def split_half(a):
    half = len(a) >> 1
    return a[:half], a[half:]
Ruslanas Balčiūnas
fuente
¡Uso inteligente del desplazamiento binario!
Janusz Skonieczny
0

Con pistas de @ChristopheD

def line_split(N, K=1):
    length = len(N)
    return [N[i*length/K:(i+1)*length/K] for i in range(K)]

A = [0,1,2,3,4,5,6,7,8,9]
print line_split(A,1)
print line_split(A,2)
PunjCoder
fuente
0
#for python 3
    A = [0,1,2,3,4,5]
    l = len(A)/2
    B = A[:int(l)]
    C = A[int(l):]       
SuperGuy10
fuente
0

Otra visión de este problema en 2020 ... Aquí hay una generalización del problema. Interpreto que 'divide una lista por la mitad' es ... (es decir, solo dos listas y no habrá derrame a una tercera matriz en caso de que haya una extraña, etc.). Por ejemplo, si la longitud de la matriz es 19 y una división entre dos usando // operador da 9, y terminaremos teniendo dos matrices de longitud 9 y una matriz (tercera) de longitud 1 (en total tres matrices). Si quisiéramos una solución general para dar dos matrices todo el tiempo, asumiré que estamos contentos con las matrices dúo resultantes que no tienen la misma longitud (una será más larga que la otra). Y que se supone que está bien tener el orden mezclado (alternando en este caso).

"""
arrayinput --> is an array of length N that you wish to split 2 times
"""
ctr = 1 # lets initialize a counter

holder_1 = []
holder_2 = []

for i in range(len(arrayinput)): 

    if ctr == 1 :
        holder_1.append(arrayinput[i])
    elif ctr == 2: 
        holder_2.append(arrayinput[i])

    ctr += 1 

    if ctr > 2 : # if it exceeds 2 then we reset 
        ctr = 1 

Este concepto funciona para cualquier cantidad de partición de la lista que desee (tendría que ajustar el código dependiendo de cuántas partes de la lista desee). Y es bastante sencillo de interpretar. Para acelerar las cosas, incluso puede escribir este bucle en cython / C / C ++ para acelerar las cosas. Por otra parte, probé este código en listas relativamente pequeñas ~ 10,000 filas y termina en una fracción de segundo.

Solo mis dos centavos.

¡Gracias!

aaronlhe
fuente