Diviser la liste en listes plus petites (diviser en deux)

150

Je cherche un moyen de diviser facilement une liste de python en deux.

Donc, si j'ai un tableau:

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

Je pourrais obtenir:

B = [0,1,2]

C = [3,4,5]
corymathews
la source

Réponses:

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

Si vous voulez une fonction:

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
la source
70
Vous devez forcer la division int dans Python 3. // est requis.
Stefan Kendall
4
Belle solution, merci. Il fonctionne également avec des fractions comme 80/20 en Python3B = A[:(len(A) // 10) * 8] C = A[(len(A) // 10) * 8:]
Gergely M
87

Une solution un peu plus générique (vous pouvez spécifier le nombre de pièces que vous voulez, pas seulement diviser `` en deux ''):

EDIT : publication mise à jour pour gérer les longueurs de liste impaires

EDIT2 : mettre à jour le post à nouveau sur la base des commentaires informatifs 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
la source
2
Lorsque la liste ne se divise pas uniformément (par exemple, split_list ([1,2,3], 2)), cela renverra en fait Want_parts + 1 listes.
Brian
3
Une meilleure façon, je pense, serait: length = len (alist); return [alist [i * longueur // pièces_voulues: (i + 1) * longueur // pièces_voulues] pour i dans la plage (pièces_voulues)]. De cette façon, vous obtenez une distribution aussi uniforme que possible, et obtenez toujours exactement les éléments voulus_parts (même les pads avec [] si want_parts> len (A))
Brian
2
salut .. que signifie le symbole "//" ??
frazman
2
@Fraz Its est conçu comme un commentaire en ligne. Ignorez "// Want_parts" et "// Want_parts" pour que le script s'exécute.
PunjCoder
19
//signifie division entière. Ils ne doivent pas être laissés de côté car ils sont tout à fait essentiels pour faire ce travail.
Alphadelta14
43
f = lambda A, n=3: [A[i:i+n] for i in range(0, len(A), n)]
f(A)

n - la longueur prédéfinie des tableaux de résultats

Jaro
la source
1
Cela fonctionne très bien dans ma situation, mais il ajoute chaque autre dernier index de chaque liste dans sa propre liste. Difficile à expliquer. Veuillez répondre si vous pouvez aider et je vous expliquerai plus.
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

Tester:

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

résultat:

[[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13]]
Siamand
la source
1
également utile pour convertir une liste en matrice
mpgn
Cela fonctionne, mais pas tout à fait. J'utilise cette fonction en boucle et les longueurs varient. En d' autres termes: for i,j in zip(list,lengths): print(split(i,j)). Les listes listet lengthsont la même longueur. j est alterné: 5,4,5,4,5, et la fonction de division fonctionne sur les deux premières alternances, c'est-à-dire qu'elle divise la première ide la liste par 5 et 4, MAIS à l'itération suivante, elle la divise en 4,4, 1. : \ Veuillez répondre si vous souhaitez que je vous explique plus (postez une nouvelle question)
Mike Issa
15

Si vous ne vous souciez pas de la commande ...

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

list[::2]obtient chaque deuxième élément de la liste à partir du 0e élément.
list[1::2]obtient chaque deuxième élément de la liste à partir du premier élément.

sentythee
la source
4
Nommez soigneusement l'argument listavec ombrage de l'élément list(...)intégré. J'ai vu lstet list_utilisé couramment pour l'éviter.
Taylor Edmiston
3
cela semble le plus pythonique (en ignorant le nom incorrect)
Tjorriemorrie
12

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

John Montgomery
la source
Je pense que vous avez oublié la division par 2 étapes. :)
Stefan Kendall
11

Voici une solution courante, diviser arr en partie count

def split(arr, count):
     return [arr[i::count] for i in range(count)]
Chris Song
la source
Ceci perd l'ordre de la liste
Timmah
9
def splitter(A):
    B = A[0:len(A)//2]
    C = A[len(A)//2:]

 return (B,C)

J'ai testé, et la double barre oblique est nécessaire pour forcer la division int en python 3. Mon message d'origine était correct, bien que wysiwyg ait cassé dans Opera, pour une raison quelconque.

Stefan Kendall
la source
il ne gère pas les len impairs (A) - avez-vous une solution pour cela?
N997
6

Il existe un reçu officiel Python pour le cas plus généralisé de fractionnement d'un tableau en tableaux plus petits de taille 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)

Cet extrait de code provient de la page de documentation python itertools .

Jonathan Berger
la source
6

Utilisation du découpage de liste . La syntaxe est essentiellementmy_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]

Pour obtenir la première moitié de la liste, vous coupez du premier index à len(i)//2(où //est la division entière - donc 3//2 will give the floored result of1 , instead of the invalid list index of1,5`):

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

.. et permutez les valeurs pour obtenir la seconde moitié:

>>> i[len(i)//2:]
[3, 4, 5]
dbr
la source
Qu'en est-il des
@ N997 Le code devrait toujours fonctionner; vous vous retrouvez juste avec un nombre différent d'articles dans chaque liste. Donc, disons que la liste est longue de trois éléments, l'opérateur de division étage le résultat ainsi 3//2donne 1, alors vous obtenez i[:1]ce qui vous donne [0]et i[1:]ce qui donne[1, 2]
dbr
3

Si vous avez une grande liste, il est préférable d'utiliser itertools et d'écrire une fonction pour produire chaque partie au besoin:

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)]

Vous pouvez utiliser ceci comme:

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

size = len(A) // 2

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

La sortie est:

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

Merci à @thefourtheye et @Bede Constantinides

MA Heshmat Khah
la source
3

10 ans plus tard .. j'ai pensé - pourquoi ne pas en ajouter un autre:

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

Bien que les réponses ci-dessus soient plus ou moins correctes, vous pouvez rencontrer des problèmes si la taille de votre tableau n'est pas divisible par 2, car le fait d' a / 2être étrange est un flottant en python 3.0, et dans la version antérieure si vous spécifiez from __future__ import divisionau début de votre script. Dans tous les cas, il vaut mieux opter pour la division entière, c'est a // 2-à- dire pour obtenir la compatibilité "en avant" de votre code.

user91259
la source
2

Ceci est similaire à d'autres solutions, mais un peu plus rapide.

# 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
la source
Utilisation intelligente du décalage binaire!
Janusz Skonieczny le
0

Avec des conseils 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
la source
0
#for python 3
    A = [0,1,2,3,4,5]
    l = len(A)/2
    B = A[:int(l)]
    C = A[int(l):]       
SuperGuy10
la source
0

Une autre prise sur ce problème en 2020 ... Voici une généralisation du problème. J'interprète le «diviser une liste en deux» comme étant .. (c'est-à-dire deux listes seulement et il n'y aura pas de débordement vers un troisième tableau en cas de sortie étrange, etc.). Par exemple, si la longueur du tableau est 19 et qu'une division par deux en utilisant l'opérateur // donne 9, et nous finirons par avoir deux tableaux de longueur 9 et un tableau (troisième) de longueur 1 (donc au total trois tableaux). Si nous voulons une solution générale pour donner deux tableaux tout le temps, je suppose que nous sommes satisfaits des tableaux duo résultants qui ne sont pas égaux en longueur (l'un sera plus long que l'autre). Et que son supposé être ok pour avoir l'ordre mélangé (en alternance dans ce cas).

"""
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 

Ce concept fonctionne pour n'importe quelle quantité de partition de liste que vous le souhaitez (vous devrez modifier le code en fonction du nombre de parties de liste souhaitées). Et c'est plutôt simple à interpréter. Pour accélérer les choses, vous pouvez même écrire cette boucle dans cython / C / C ++ pour accélérer les choses. Là encore, j'ai essayé ce code sur des listes relativement petites d'environ 10000 lignes et il se termine en une fraction de seconde.

Juste mes deux cents.

Merci!

Aaronlhe
la source