Liste in kleinere Listen aufteilen (in zwei Hälften teilen)


150

Ich suche nach einer Möglichkeit, eine Python-Liste einfach in zwei Hälften zu teilen.

Wenn ich also ein Array habe:

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

Ich würde bekommen können:

B = [0,1,2]

C = [3,4,5]

Antworten:


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

Wenn Sie eine Funktion wünschen:

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)

70
Sie müssen die int-Division in Python 3 erzwingen. // ist erforderlich.
Stefan Kendall

4
Gute Lösung, danke. Es funktioniert auch mit Brüchen wie 80/20 in Python3B = A[:(len(A) // 10) * 8] C = A[(len(A) // 10) * 8:]
Gergely M

87

Eine etwas allgemeinere Lösung (Sie können die Anzahl der gewünschten Teile angeben und nicht nur in zwei Hälften teilen):

BEARBEITEN : Der Beitrag wurde aktualisiert, um ungerade Listenlängen zu verarbeiten

EDIT2 : Aktualisiere den Beitrag erneut basierend auf Brians informativen Kommentaren

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)

2
Wenn sich die Liste nicht gleichmäßig teilt (z. B. split_list ([1,2,3], 2)), werden tatsächlich want_parts + 1-Listen zurückgegeben.
Brian

3
Ein besserer Weg, denke ich, wäre: Länge = Länge (Alist); return [alist [i * Länge // gewollte Teile: (i + 1) * Länge // gewollte Teile] für i im Bereich (gewollte Teile)]. Auf diese Weise erhalten Sie eine möglichst gleichmäßige Verteilung und erhalten immer genau die gewünschten Teile (auch Pads mit [], wenn die gewünschten Teile> len (A))
Brian,

2
hi .. was bedeutet das symbol "//" ??
Frazman

2
@Fraz Es ist als Inline-Kommentar gemeint. Ignorieren Sie "// want_parts" und "// want_parts", damit das Skript ausgeführt wird.
PunjCoder

19
//bedeutet ganzzahlige Division. Sie sollten nicht ausgelassen werden, da sie für diese Arbeit sehr wichtig sind.
Alphadelta14

43
f = lambda A, n=3: [A[i:i+n] for i in range(0, len(A), n)]
f(A)

n - die vordefinierte Länge der Ergebnisarrays


1
Dies funktioniert in meiner Situation hervorragend, fügt jedoch jeden zweiten Index jeder Liste in eine eigene Liste ein. Schwer zu erklären. Bitte antworten Sie, wenn Sie helfen können und ich werde mehr erklären.
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

Prüfung:

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

Ergebnis:

[[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13]]

1
auch nützlich, um Liste in Matrix zu konvertieren
mpgn

Das funktioniert, aber nicht ganz. Ich benutze diese Funktion in einer Schleife und die Längen variieren. Mit anderen Worten : for i,j in zip(list,lengths): print(split(i,j)). Die listund lengthsListen haben die gleiche Länge. j wechselt: 5,4,5,4,5, und die Aufteilungsfunktion arbeitet bei den ersten beiden Abwechslungen, dh sie teilt die erste ider Liste durch 5 und 4, ABER bei der nächsten Iteration teilt sie sie bei 4,4 auf. 1. : \ Bitte antworten Sie, wenn Sie möchten, dass ich mehr erkläre (eine neue Frage posten)
Mike Issa

15

Wenn Sie sich nicht für die Bestellung interessieren ...

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

list[::2]Ruft jedes zweite Element in der Liste ab dem 0. Element ab.
list[1::2]Ruft jedes zweite Element in der Liste ab dem ersten Element ab.


4
Sorgfältige Benennung des Args listdurch Abschatten des list(...)eingebauten Arg . Ich habe allgemein gesehen lstund list_verwendet, um es zu vermeiden.
Taylor Edmiston

3
das fühlt sich am pythonischsten an (ignoriert die falsche Benennung)
Tjorriemorrie


11

Hier ist eine gängige Lösung, die arr in count part aufteilt

def split(arr, count):
     return [arr[i::count] for i in range(count)]

Dies verliert die Reihenfolge der Liste
Timmah

9
def splitter(A):
    B = A[0:len(A)//2]
    C = A[len(A)//2:]

 return (B,C)

Ich habe getestet, und der doppelte Schrägstrich ist erforderlich, um die int-Teilung in Python 3 zu erzwingen. Mein ursprünglicher Beitrag war korrekt, obwohl wysiwyg aus irgendeinem Grund in Opera pleite war.


es behandelt nicht ungerade len (A) - haben Sie eine Lösung dafür?
N997

6

Es gibt ein offizielles Python-Rezept für den allgemeineren Fall der Aufteilung eines Arrays in kleinere Arrays mit einer Größe 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)

Dieses Code-Snippet stammt von der Python-itertools-Dokumentseite .


6

Mit Liste schneiden . Die Syntax ist grundsätzlichmy_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]

Um die erste Hälfte der Liste zu erhalten, schneiden Sie vom ersten Index nach len(i)//2(wo //ist die Ganzzahldivision - also 3//2 will give the floored result of1 , instead of the invalid list index of1,5`):

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

..und tauschen Sie die Werte aus, um die zweite Hälfte zu erhalten:

>>> i[len(i)//2:]
[3, 4, 5]

was ist mit ungeraden len Listen)
N997

@ N997 Der Code sollte noch funktionieren; Sie haben nur eine unterschiedliche Anzahl von Elementen in jeder Liste. Nehmen wir also an, die Liste ist drei Elemente lang, der Divisionsoperator 3//2gibt das Ergebnis so aus 1, dass Sie das erhalten i[:1], was Sie erhalten [0]und i[1:]das gibt[1, 2]
dbr

3

Wenn Sie eine große Liste haben, ist es besser, itertools zu verwenden und eine Funktion zu schreiben, um jedes Teil nach Bedarf zu erhalten:

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

Sie können dies wie folgt verwenden:

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

size = len(A) // 2

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

Die Ausgabe ist:

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

Vielen Dank an @thefourtheye und @Bede Constantinides


3

10 Jahre später .. Ich dachte - warum nicht noch einen hinzufügen:

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

2

Obwohl die obigen Antworten mehr oder weniger korrekt sind, können Probleme auftreten, wenn die Größe Ihres Arrays nicht durch 2 teilbar a / 2ist Geben Sie from __future__ import divisionam Anfang Ihres Skripts an. In jedem Fall ist es besser, sich für eine Ganzzahldivision zu entscheiden, dh a // 2um die "Vorwärts" -Kompatibilität Ihres Codes zu erreichen.


2

Dies ähnelt anderen Lösungen, ist jedoch etwas schneller.

# 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:]

Cleverer Einsatz von Binärverschiebung!
Janusz Skonieczny

0

Mit Hinweisen von @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)

0
#for python 3
    A = [0,1,2,3,4,5]
    l = len(A)/2
    B = A[:int(l)]
    C = A[int(l):]       

0

Eine weitere Sichtweise auf dieses Problem im Jahr 2020 ... Hier ist eine Verallgemeinerung des Problems. Ich interpretiere das 'Teilen einer Liste in zwei Hälften' als .. (dh nur zwei Listen und es darf kein Übergreifen auf ein drittes Array im Falle eines ungeraden Outs usw. geben). Wenn zum Beispiel die Array-Länge 19 ist und eine Division durch zwei mit dem Operator // 9 ergibt, erhalten wir zwei Arrays der Länge 9 und ein Array (Drittel) der Länge 1 (also insgesamt drei Arrays). Wenn wir möchten, dass eine allgemeine Lösung immer zwei Arrays ergibt, gehe ich davon aus, dass wir mit den resultierenden Duo-Arrays zufrieden sind, die nicht gleich lang sind (eines ist länger als das andere). Und dass davon ausgegangen wird, dass es in Ordnung ist, die Reihenfolge zu mischen (in diesem Fall abwechselnd).

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

Dieses Konzept funktioniert für eine beliebige Anzahl von Listenpartitionen, wie Sie möchten (Sie müssten den Code abhängig von der Anzahl der gewünschten Listenteile anpassen). Und ist ziemlich einfach zu interpretieren. Um die Dinge zu beschleunigen, können Sie diese Schleife sogar in Cython / C / C ++ schreiben, um die Dinge zu beschleunigen. Andererseits habe ich diesen Code in relativ kleinen Listen mit ~ 10.000 Zeilen ausprobiert und er endet in Sekundenbruchteilen.

Nur meine zwei Cent.

Vielen Dank!

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.