Aufteilen einer Liste in N Teile von ungefähr gleicher Länge


148

Was ist der beste Weg, um eine Liste in ungefähr gleiche Teile zu teilen ? Wenn die Liste beispielsweise 7 Elemente enthält und in 2 Teile aufgeteilt ist, möchten wir 3 Elemente in einem Teil erhalten, und der andere sollte 4 Elemente enthalten.

Ich suche so etwas even_split(L, n), das Lin nTeile zerbricht .

def chunks(L, n):
    """ Yield successive n-sized chunks from L.
    """
    for i in range(0, len(L), n):
        yield L[i:i+n]

Der obige Code gibt Blöcke von 3 statt 3 Blöcken an. Ich könnte einfach transponieren (darüber iterieren und das erste Element jeder Spalte nehmen, diesen Teil eins nennen, dann das zweite nehmen und es in Teil zwei setzen usw.), aber das zerstört die Reihenfolge der Elemente.

Antworten:


65

Dieser Code ist aufgrund von Rundungsfehlern fehlerhaft. Benutze es nicht!!!

assert len(chunkIt([1,2,3], 10)) == 10  # fails

Hier ist eine, die funktionieren könnte:

def chunkIt(seq, num):
    avg = len(seq) / float(num)
    out = []
    last = 0.0

    while last < len(seq):
        out.append(seq[int(last):int(last + avg)])
        last += avg

    return out

Testen:

>>> chunkIt(range(10), 3)
[[0, 1, 2], [3, 4, 5], [6, 7, 8, 9]]
>>> chunkIt(range(11), 3)
[[0, 1, 2], [3, 4, 5, 6], [7, 8, 9, 10]]
>>> chunkIt(range(12), 3)
[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]]

9
Ihr Beispiel funktioniert nicht für >>> chunkIt(range(8), 6)=>[[0], [1], [2, 3], [4], [5], [6], [7]]
nopper

1
@nopper, ich habe eine "if num == 1:" - Bedingung hinzugefügt, um diesen Randfall zu behandeln.
Paulie4

24
Neue Besucher: Bitte verwenden oder bewerten Sie diesen Code nicht , er ist defekt. zB chunkIt(range(10), 9)sollte 9 Teile zurückgeben, aber das tut es nicht.
wim

3
Dieser Kommentarthread ist wirklich verwirrend, da die Antwort mehrmals bearbeitet wurde. Ist das eine gute Antwort? Keine gute Antwort?
Conchoecia

6
@conchoecia Keine gute Antwort, scrollen Sie weiter nach unten. Dies wurde bisher nur einmal bearbeitet, und es war nur eine triviale Bearbeitung (2 Leerzeicheneinzug in 4 geändert). Leider wurde das OP "user248237dfsf" seit über 3 Jahren nicht mehr auf der Website gesehen, sodass wenig Hoffnung besteht, dass die akzeptierte Antwort geändert wird.
wim

182

Sie können es ziemlich einfach als Listengenerator schreiben:

def split(a, n):
    k, m = divmod(len(a), n)
    return (a[i * k + min(i, m):(i + 1) * k + min(i + 1, m)] for i in range(n))

Beispiel:

>>> list(split(range(11), 3))
[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10]]

Fügen Sie n = min(n, len(a)) # don't create empty bucketsin Zeile 1 ein, um zu vermeiden, dass in Szenarien wie list(split(range(X, Y)))whereX < Y
abanana

Da ich meinen Kommentar nicht bearbeiten kann, sollte ich hinzufügen, dass meine vorherige Änderung möglicherweise einen Fehler durch Division durch Null auslösen kann, wenn die Liste leer ist, sodass diese entweder extern gesteuert oder der Lösung hinzugefügt werden muss.
Abanana

4
Von N Antworten auf SO ist dies die einzige, die alle meine Tests bestanden hat. gj!
Avishayp

2
stackoverflow.com/a/37414115/210971 verwendet dieselbe Methode, funktioniert jedoch auch für leere Listen und 0-Split-Zähler.
LookAheadAtYourTypes

Wunderschönen! Außerdem kann n dazu gebracht werden, als batch_size zu arbeiten, indem k und n in der return-Anweisung
ausgetauscht werden

161

Dies ist die Daseinsberechtigung für numpy.array_split*:

>>> import numpy as np
>>> print(*np.array_split(range(10), 3))
[0 1 2 3] [4 5 6] [7 8 9]
>>> print(*np.array_split(range(10), 4))
[0 1 2] [3 4 5] [6 7] [8 9]
>>> print(*np.array_split(range(10), 5))
[0 1] [2 3] [4 5] [6 7] [8 9]

* Gutschrift an Zero Piraeus in Raum 6


1
Was ist *in printfür?
Yuqli

2
Hey @yuqli, es konvertiert eine Liste von etwas in einzelne Argumente in eine Funktion. versuche print(L)und drucke (* L). Siehe auch stackoverflow.com/a/36908/2184122 oder suchen Sie nach "Python-Verwendung von Sternchen".
Robert Lugg

121

Solange Sie nichts Dummes wie ununterbrochene Brocken wollen:

>>> def chunkify(lst,n):
...     return [lst[i::n] for i in xrange(n)]
... 
>>> chunkify(range(13), 3)
[[0, 3, 6, 9, 12], [1, 4, 7, 10], [2, 5, 8, 11]]

14
Ich würde nicht sagen, dass kontinuierliche Brocken albern sind. Vielleicht möchten Sie die Chunks sortiert halten (z. B. Chunk [0] <Chunk [1]).
Tixxit

1
Ich habe gescherzt. Aber wenn es Sie wirklich nicht interessiert hat, ist dieser Weg mit Listenverständnis nett und prägnant.
Job

3
Dies wird mit einem Schritt von n
smci

8
Wenn Sie diese Ausgabe an 'zip' senden, erhalten Sie Ihre geordnete Liste: zip(*chunkify(range(13), 3))Ergebnisse in[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11)]
gens

2
Diese Lösung funktioniert einwandfrei, bis Sie die Reihenfolge der Liste gleich bleiben müssen.
S7anley

18

Ändern des Codes, um nBlöcke zu ergeben, anstatt Blöcke von n:

def chunks(l, n):
    """ Yield n successive chunks from l.
    """
    newn = int(len(l) / n)
    for i in xrange(0, n-1):
        yield l[i*newn:i*newn+newn]
    yield l[n*newn-newn:]

l = range(56)
three_chunks = chunks (l, 3)
print three_chunks.next()
print three_chunks.next()
print three_chunks.next()

was gibt:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17]
[18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35]
[36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55]

Dies ordnet die zusätzlichen Elemente der endgültigen Gruppe zu, die nicht perfekt ist, aber gut in Ihrer Spezifikation von "ungefähr N gleichen Teilen" liegt :-) Damit meine ich, 56 Elemente wären besser als (19,19,18), während dies ergibt (18, 18, 20).

Sie können die ausgewogenere Ausgabe mit dem folgenden Code erhalten:

#!/usr/bin/python
def chunks(l, n):
    """ Yield n successive chunks from l.
    """
    newn = int(1.0 * len(l) / n + 0.5)
    for i in xrange(0, n-1):
        yield l[i*newn:i*newn+newn]
    yield l[n*newn-newn:]

l = range(56)
three_chunks = chunks (l, 3)
print three_chunks.next()
print three_chunks.next()
print three_chunks.next()

welche Ausgänge:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]
[19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37]
[38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55]

das gibt mir ein seltsames Ergebnis. für p in Chunks (Bereich (54), 3): print len ​​(p) gibt 18, 18, 51 zurück ...

Behoben, dass es die Endausbeute war.
Paxdiablo

siehe auch eine Lösung unter Link
Jakob Kroeker

Dies ist die nützlichste Antwort für praktische Überlegungen. Vielen Dank!
MVChr

Wenn ich das benutze, for x in chunks(mylist,num): print xbekomme ich die gewünschten Stücke, aber zwischen ihnen bekomme ich eine leere Liste. Irgendeine Idee warum? Das heißt, ich bekomme viele [], eine nach jedem Stück.
Synaptik

12

Wenn Sie nElemente in grobe kBlöcke unterteilen, können Sie n % kBlöcke 1 Element größer als die anderen Blöcke machen, um die zusätzlichen Elemente zu verteilen.

Der folgende Code gibt Ihnen die Länge für die Chunks an:

[(n // k) + (1 if i < (n % k) else 0) for i in range(k)]

Beispiel: n=11, k=3Ergebnisse in[4, 4, 3]

Sie können dann einfach die Startindizes für die Chunks berechnen:

[i * (n // k) + min(i, n % k) for i in range(k)]

Beispiel: n=11, k=3Ergebnisse in[0, 4, 8]

Wenn i+1wir den th-Block als Grenze verwenden, erhalten wir, dass der ith-Block der Liste lmit len nist

l[i * (n // k) + min(i, n % k):(i+1) * (n // k) + min(i+1, n % k)]

Als letzten Schritt erstellen Sie eine Liste aus allen Blöcken mit Listenverständnis:

[l[i * (n // k) + min(i, n % k):(i+1) * (n // k) + min(i+1, n % k)] for i in range(k)]

Beispiel: n=11, k=3, l=range(n)Ergebnisse in[range(0, 4), range(4, 8), range(8, 11)]


6

Dies führt die Aufteilung durch einen einzelnen Ausdruck durch:

>>> myList = range(18)
>>> parts = 5
>>> [myList[(i*len(myList))//parts:((i+1)*len(myList))//parts] for i in range(parts)]
[[0, 1, 2], [3, 4, 5, 6], [7, 8, 9], [10, 11, 12, 13], [14, 15, 16, 17]]

Die Liste in diesem Beispiel hat die Größe 18 und ist in 5 Teile unterteilt. Die Größe der Teile unterscheidet sich in nicht mehr als einem Element.



4

Hier ist eine, die hinzugefügt wird None, um die Listen gleich lang zu machen

>>> from itertools import izip_longest
>>> def chunks(l, n):
    """ Yield n successive chunks from l. Pads extra spaces with None
    """
    return list(zip(*izip_longest(*[iter(l)]*n)))

>>> l=range(54)

>>> chunks(l,3)
[(0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51), (1, 4, 7, 10, 13, 16, 19, 22, 25, 28, 31, 34, 37, 40, 43, 46, 49, 52), (2, 5, 8, 11, 14, 17, 20, 23, 26, 29, 32, 35, 38, 41, 44, 47, 50, 53)]

>>> chunks(l,4)
[(0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52), (1, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45, 49, 53), (2, 6, 10, 14, 18, 22, 26, 30, 34, 38, 42, 46, 50, None), (3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 43, 47, 51, None)]

>>> chunks(l,5)
[(0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50), (1, 6, 11, 16, 21, 26, 31, 36, 41, 46, 51), (2, 7, 12, 17, 22, 27, 32, 37, 42, 47, 52), (3, 8, 13, 18, 23, 28, 33, 38, 43, 48, 53), (4, 9, 14, 19, 24, 29, 34, 39, 44, 49, None)]

4

Hier ist meine Lösung:

def chunks(l, amount):
    if amount < 1:
        raise ValueError('amount must be positive integer')
    chunk_len = len(l) // amount
    leap_parts = len(l) % amount
    remainder = amount // 2  # make it symmetrical
    i = 0
    while i < len(l):
        remainder += leap_parts
        end_index = i + chunk_len
        if remainder >= amount:
            remainder -= amount
            end_index += 1
        yield l[i:end_index]
        i = end_index

Produziert

    >>> list(chunks([1, 2, 3, 4, 5, 6, 7], 3))
    [[1, 2], [3, 4, 5], [6, 7]]

4

Hier ist ein Generator, der eine beliebige positive (ganzzahlige) Anzahl von Chunks verarbeiten kann. Wenn die Anzahl der Chunks größer als die Länge der Eingabeliste ist, sind einige Chunks leer. Dieser Algorithmus wechselt zwischen kurzen und langen Blöcken, anstatt sie zu trennen.

Ich habe auch Code zum Testen der ragged_chunksFunktion eingefügt.

''' Split a list into "ragged" chunks

    The size of each chunk is either the floor or ceiling of len(seq) / chunks

    chunks can be > len(seq), in which case there will be empty chunks

    Written by PM 2Ring 2017.03.30
'''

def ragged_chunks(seq, chunks):
    size = len(seq)
    start = 0
    for i in range(1, chunks + 1):
        stop = i * size // chunks
        yield seq[start:stop]
        start = stop

# test

def test_ragged_chunks(maxsize):
    for size in range(0, maxsize):
        seq = list(range(size))
        for chunks in range(1, size + 1):
            minwidth = size // chunks
            #ceiling division
            maxwidth = -(-size // chunks)
            a = list(ragged_chunks(seq, chunks))
            sizes = [len(u) for u in a]
            deltas = all(minwidth <= u <= maxwidth for u in sizes)
            assert all((sum(a, []) == seq, sum(sizes) == size, deltas))
    return True

if test_ragged_chunks(100):
    print('ok')

Wir können dies etwas effizienter gestalten, indem wir die Multiplikation in den rangeAufruf exportieren , aber ich denke, die vorherige Version ist besser lesbar (und DRYer).

def ragged_chunks(seq, chunks):
    size = len(seq)
    start = 0
    for i in range(size, size * chunks + 1, size):
        stop = i // chunks
        yield seq[start:stop]
        start = stop

3

Schauen Sie sich numpy.split an :

>>> a = numpy.array([1,2,3,4])
>>> numpy.split(a, 2)
[array([1, 2]), array([3, 4])]

5
Und numpy.array_split () ist noch angemessener, weil es sich grob aufteilt.
Yariv

11
Dies funktioniert nicht, wenn die Arraygröße nicht durch die Anzahl der Teilungen teilbar ist.
Dan

1
Dies ist eine falsche Antwort. Ihre Lösung gibt eine Liste der ndarrays zurück, keine Liste der Listen
Chłop Z Lasu

3

Implementierung mit der Methode numpy.linspace.

Geben Sie einfach die Anzahl der Teile an, in die das Array unterteilt werden soll. Die Unterteilungen sind nahezu gleich groß.

Beispiel:

import numpy as np   
a=np.arange(10)
print "Input array:",a 
parts=3
i=np.linspace(np.min(a),np.max(a)+1,parts+1)
i=np.array(i,dtype='uint16') # Indices should be floats
split_arr=[]
for ind in range(i.size-1):
    split_arr.append(a[i[ind]:i[ind+1]]
print "Array split in to %d parts : "%(parts),split_arr

Gibt:

Input array: [0 1 2 3 4 5 6 7 8 9]
Array split in to 3 parts :  [array([0, 1, 2]), array([3, 4, 5]), array([6, 7, 8, 9])]

3

Meine Lösung, leicht zu verstehen

def split_list(lst, n):
    splitted = []
    for i in reversed(range(1, n + 1)):
        split_point = len(lst)//i
        splitted.append(lst[:split_point])
        lst = lst[split_point:]
    return splitted

Und der kürzeste Einzeiler auf dieser Seite (geschrieben von meinem Mädchen)

def split(l, n):
    return [l[int(i*len(l)/n):int((i+1)*len(l)/n-1)] for i in range(n)]

Zu Ihrer Information: Ihr Einzeiler ist kaputt und führt zu falschen Ergebnissen. Der andere funktioniert wunderbar.
Paulo Freitas

2

Listenverständnis verwenden:

def divide_list_to_chunks(list_, n):
    return [list_[start::n] for start in range(n)]

Dies behebt nicht das Problem, alle Chunks gleichmäßig zu machen.
SuperBiasedMan

0

Ein anderer Weg wäre so etwas, die Idee hier ist, Zackenbarsch zu verwenden, aber loszuwerden None. In diesem Fall werden im ersten Teil der Liste alle "kleinen Teile" aus Elementen und im späteren Teil der Liste "größere Teile" gebildet. Die Länge von 'größeren Teilen' beträgt len ​​(small_parts) + 1. Wir müssen x als zwei verschiedene Unterteile betrachten.

from itertools import izip_longest

import numpy as np

def grouper(n, iterable, fillvalue=None): # This is grouper from itertools
    "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"
    args = [iter(iterable)] * n
    return izip_longest(fillvalue=fillvalue, *args)

def another_chunk(x,num):
    extra_ele = len(x)%num #gives number of parts that will have an extra element 
    small_part = int(np.floor(len(x)/num)) #gives number of elements in a small part

    new_x = list(grouper(small_part,x[:small_part*(num-extra_ele)]))
    new_x.extend(list(grouper(small_part+1,x[small_part*(num-extra_ele):])))

    return new_x

Die Art und Weise, wie ich es eingerichtet habe, gibt eine Liste von Tupeln zurück:

>>> x = range(14)
>>> another_chunk(x,3)
[(0, 1, 2, 3), (4, 5, 6, 7, 8), (9, 10, 11, 12, 13)]
>>> another_chunk(x,4)
[(0, 1, 2), (3, 4, 5), (6, 7, 8, 9), (10, 11, 12, 13)]
>>> another_chunk(x,5)
[(0, 1), (2, 3, 4), (5, 6, 7), (8, 9, 10), (11, 12, 13)]
>>> 

0

Hier ist eine weitere Variante, bei der die "verbleibenden" Elemente nacheinander gleichmäßig auf alle Blöcke verteilt werden, bis keine mehr vorhanden sind. In dieser Implementierung treten die größeren Blöcke zu Beginn des Prozesses auf.

def chunks(l, k):
  """ Yield k successive chunks from l."""
  if k < 1:
    yield []
    raise StopIteration
  n = len(l)
  avg = n/k
  remainders = n % k
  start, end = 0, avg
  while start < n:
    if remainders > 0:
      end = end + 1
      remainders = remainders - 1
    yield l[start:end]
    start, end = end, end+avg

Generieren Sie beispielsweise 4 Blöcke aus einer Liste von 14 Elementen:

>>> list(chunks(range(14), 4))
[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10], [11, 12, 13]]
>>> map(len, list(chunks(range(14), 4)))
[4, 4, 3, 3]

0

Das gleiche wie Aufgabe der Antwort, sondern berücksichtigt Listen mit Größe , die kleiner als die Anzahl der chuncks.

def chunkify(lst,n):
    [ lst[i::n] for i in xrange(n if n < len(lst) else len(lst)) ]

Wenn n (Anzahl der Chunks) 7 ist und lst (die zu teilende Liste) [1, 2, 3] ist, sind die Chunks [[0], [1], [2]] anstelle von [[0], [1 ], [2], [], [], [], []]


0

Sie könnten auch verwenden:

split=lambda x,n: x if not x else [x[:n]]+[split([] if not -(len(x)-n) else x[-(len(x)-n):],n)][0]

split([1,2,3,4,5,6,7,8,9],2)

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

0
def evenly(l, n):
    len_ = len(l)
    split_size = len_ // n
    split_size = n if not split_size else split_size
    offsets = [i for i in range(0, len_, split_size)]
    return [l[offset:offset + split_size] for offset in offsets]

Beispiel:

l = [a for a in range(97)] sollte aus 10 Teilen bestehen, die jeweils 9 Elemente außer dem letzten haben.

Ausgabe:

[[0, 1, 2, 3, 4, 5, 6, 7, 8],
 [9, 10, 11, 12, 13, 14, 15, 16, 17],
 [18, 19, 20, 21, 22, 23, 24, 25, 26],
 [27, 28, 29, 30, 31, 32, 33, 34, 35],
 [36, 37, 38, 39, 40, 41, 42, 43, 44],
 [45, 46, 47, 48, 49, 50, 51, 52, 53],
 [54, 55, 56, 57, 58, 59, 60, 61, 62],
 [63, 64, 65, 66, 67, 68, 69, 70, 71],
 [72, 73, 74, 75, 76, 77, 78, 79, 80],
 [81, 82, 83, 84, 85, 86, 87, 88, 89],
 [90, 91, 92, 93, 94, 95, 96]]

0

Angenommen, Sie möchten eine Liste [1, 2, 3, 4, 5, 6, 7, 8] in 3 Elementlisten aufteilen

wie [[1,2,3], [4, 5, 6], [7, 8]] , wo, wenn die letzten verbleibenden Elemente kleiner als 3 sind, sie zusammen gruppiert werden.

my_list = [1, 2, 3, 4, 5, 6, 7, 8]
my_list2 = [my_list[i:i+3] for i in range(0, len(my_list), 3)]
print(my_list2)

Ausgabe: [[1,2,3], [4, 5, 6], [7, 8]]

Wenn die Länge eines Teils 3 beträgt. Ersetzen Sie 3 durch Ihre eigene Blockgröße.


0

1>

import numpy as np

data # your array

total_length = len(data)
separate = 10
sub_array_size = total_length // separate
safe_separate = sub_array_size * separate

splited_lists = np.split(np.array(data[:safe_separate]), separate)
splited_lists[separate - 1] = np.concatenate(splited_lists[separate - 1], 
np.array(data[safe_separate:total_length]))

splited_lists # your output

2>

splited_lists = np.array_split(np.array(data), separate)

0
def chunk_array(array : List, n: int) -> List[List]:
    chunk_size = len(array) // n 
    chunks = []
    i = 0
    while i < len(array):
        # if less than chunk_size left add the remainder to last element
        if len(array) - (i + chunk_size + 1) < 0:
            chunks[-1].append(*array[i:i + chunk_size])
            break
        else:
            chunks.append(array[i:i + chunk_size])
            i += chunk_size
    return chunks

Hier ist meine Version (inspiriert von Max)


-1

Das Runden des Linspace und dessen Verwendung als Index ist eine einfachere Lösung als von amit12690 vorgeschlagen.

function chunks=chunkit(array,num)

index = round(linspace(0,size(array,2),num+1));

chunks = cell(1,num);

for x = 1:num
chunks{x} = array(:,index(x)+1:index(x+1));
end
end

-1
#!/usr/bin/python


first_names = ['Steve', 'Jane', 'Sara', 'Mary','Jack','Bob', 'Bily', 'Boni', 'Chris','Sori', 'Will', 'Won','Li']

def chunks(l, n):
for i in range(0, len(l), n):
    # Create an index range for l of n items:
    yield l[i:i+n]

result = list(chunks(first_names, 5))
print result

Aus diesem Link ausgewählt , und das hat mir geholfen. Ich hatte eine vordefinierte Liste.


-1

Angenommen, Sie möchten in 5 Teile teilen:

p1, p2, p3, p4, p5 = np.split(df, 5)

4
Dies gibt keine Antwort auf die Frage, z. B. wie würden Sie sie schreiben, wenn Sie nicht im Voraus wissen, dass Sie sie in fünf Teile teilen möchten. Außerdem nehmen Sie (ich vermute) Numpy und vielleicht einen Pandas-Datenrahmen an. Das OP fragt nach einer generischen Liste.
NickD

-1

Ich habe in diesem Fall selbst Code geschrieben:

def chunk_ports(port_start, port_end, portions):
    if port_end < port_start:
        return None

    total = port_end - port_start + 1

    fractions = int(math.floor(float(total) / portions))

    results = []

    # No enough to chuck.
    if fractions < 1:
        return None

    # Reverse, so any additional items would be in the first range.
    _e = port_end
    for i in range(portions, 0, -1):
        print "i", i

        if i == 1:
            _s = port_start
        else:
            _s = _e - fractions + 1

        results.append((_s, _e))

        _e = _s - 1

    results.reverse()

    return results

divid_ports (1, 10, 9) würde zurückkehren

[(1, 2), (3, 3), (4, 4), (5, 5), (6, 6), (7, 7), (8, 8), (9, 9), (10, 10)]

-1

Dieser Code funktioniert für mich (Python3-kompatibel):

def chunkify(tab, num):
    return [tab[i*num: i*num+num] for i in range(len(tab)//num+(1 if len(tab)%num else 0))]

Beispiel (für Bytearray- Typ, aber es funktioniert auch für Listen ):

b = bytearray(b'\x01\x02\x03\x04\x05\x06\x07\x08')
>>> chunkify(b,3)
[bytearray(b'\x01\x02\x03'), bytearray(b'\x04\x05\x06'), bytearray(b'\x07\x08')]
>>> chunkify(b,4)
[bytearray(b'\x01\x02\x03\x04'), bytearray(b'\x05\x06\x07\x08')]

-1

Dieser liefert Blöcke der Länge <= n,> = 0

def

 chunkify(lst, n):
    num_chunks = int(math.ceil(len(lst) / float(n))) if n < len(lst) else 1
    return [lst[n*i:n*(i+1)] for i in range(num_chunks)]

beispielsweise

>>> chunkify(range(11), 3)
[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10]]
>>> chunkify(range(11), 8)
[[0, 1, 2, 3, 4, 5, 6, 7], [8, 9, 10]]

-1

Ich habe die meisten Lösungen ausprobiert, aber sie haben in meinem Fall nicht funktioniert. Daher erstelle ich eine neue Funktion, die in den meisten Fällen und für jede Art von Array funktioniert:

import math

def chunkIt(seq, num):
    seqLen = len(seq)
    total_chunks = math.ceil(seqLen / num)
    items_per_chunk = num
    out = []
    last = 0

    while last < seqLen:
        out.append(seq[last:(last + items_per_chunk)])
        last += items_per_chunk

    return out
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.