Membagi daftar menjadi N bagian dengan panjang kira-kira sama

150

Apa cara terbaik untuk membagi daftar menjadi bagian yang kira - kira sama? Misalnya, jika daftar memiliki 7 elemen dan membaginya menjadi 2 bagian, kami ingin mendapatkan 3 elemen di satu bagian, dan yang lainnya harus memiliki 4 elemen.

Saya mencari sesuatu seperti even_split(L, n)itu pecah Lmenjadi nbeberapa bagian.

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

Kode di atas memberikan potongan 3, bukan 3 potongan. Saya hanya bisa memindahkan (iterate atas ini dan mengambil elemen pertama dari setiap kolom, memanggil bagian satu, lalu mengambil yang kedua dan meletakkannya di bagian dua, dll), tetapi itu menghancurkan pemesanan item.

wim
sumber

Jawaban:

64

Kode ini rusak karena kesalahan pembulatan. Jangan gunakan itu!!!

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

Inilah yang bisa bekerja:

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

Pengujian:

>>> 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]]
Max Shawabkeh
sumber
9
Contoh Anda tidak akan berfungsi untuk >>> chunkIt(range(8), 6)=>[[0], [1], [2, 3], [4], [5], [6], [7]]
nopper
1
@nopper, saya menambahkan persyaratan "if num == 1:" untuk menangani case edge.
paulie4
24
Pengunjung baru: tolong jangan gunakan atau hapus kode ini , itu rusak. misalnya chunkIt(range(10), 9)harus mengembalikan 9 bagian, tetapi tidak.
wim
3
Utas komentar ini benar-benar membingungkan karena jawabannya telah diedit beberapa kali. Apakah ini jawaban yang bagus? Bukan jawaban yang bagus?
conchoecia
6
@conchoecia Bukan jawaban yang bagus, teruskan ke bawah. Ini baru diedit sekali sejauh ini, dan itu hanya edit sepele (2 spasi indent berubah menjadi 4). Sayangnya OP "user248237dfsf" belum terlihat di situs selama lebih dari 3 tahun, jadi ada sedikit harapan untuk mendapatkan jawaban yang diterima berubah.
wim
183

Anda dapat menulisnya cukup sederhana sebagai generator daftar:

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

Contoh:

>>> list(split(range(11), 3))
[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10]]
tixxit
sumber
Masukkan n = min(n, len(a)) # don't create empty bucketsbaris 1 untuk menghindari pembuatan ember kosong dalam skenario seperti di list(split(range(X, Y)))manaX < Y
abanana
Melihat saya tidak dapat mengedit komentar saya - saya harus menambahkan bahwa amandemen saya sebelumnya mungkin dapat meningkatkan pembagian dengan kesalahan nol jika daftar kosong, sehingga perlu dikontrol secara eksternal atau ditambahkan ke solusi.
abanana
4
Dari jawaban N pada SO, ini adalah satu-satunya yang telah lulus semua tes saya. gj!
avishayp
2
stackoverflow.com/a/37414115/210971 menggunakan metode yang sama, tetapi juga berfungsi untuk daftar kosong dan 0 penghitung split.
LihatAheadAtYourTypes
Cantik! Juga, n dapat dibuat berfungsi sebagai batch_size dengan menukar k dan n dalam pernyataan pengembalian :)
haraprasadj
162

Ini adalah raison d'être untuk 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]

* dikreditkan ke Zero Piraeus di kamar 6

wim
sumber
1
Apa *di printuntuk?
yuqli
2
Hai @yuqli, Ini mengubah daftar sesuatu menjadi argumen individu menjadi suatu fungsi. coba print(L)dan `cetak (* L). Lihat juga stackoverflow.com/a/36908/2184122 atau cari "python use of asterisk".
Robert Lugg
121

Selama Anda tidak ingin sesuatu yang konyol seperti bongkahan berkelanjutan:

>>> 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]]
pekerjaan
sumber
14
Saya tidak akan mengatakan potongan terus menerus itu konyol. Mungkin Anda ingin menjaga chunks diurutkan (mis. Chunk [0] <chunk [1]), misalnya.
tixxit
1
Saya bercanda. Tetapi jika Anda benar-benar tidak peduli, cara ini dengan pemahaman daftar bagus dan singkat.
pekerjaan
3
Ini adalah subskrip dengan langkah n
smci
8
mengirimkan output ini ke 'zip' memberi Anda daftar yang Anda pesan: zip(*chunkify(range(13), 3))hasil di[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11)]
gens
2
Solusi ini berfungsi dengan baik, sampai Anda memerlukan urutan daftar tetap sama.
s7anley
18

Mengubah kode untuk menghasilkan npotongan daripada potongan 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()

pemberian yang mana:

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

Ini akan menetapkan elemen tambahan ke grup akhir yang tidak sempurna tetapi sesuai dengan spesifikasi "kira-kira N bagian yang sama" :-) Maksud saya, 56 elemen akan lebih baik (19,19,18) sedangkan ini memberikan (18,18,20).

Anda bisa mendapatkan hasil yang lebih seimbang dengan kode berikut:

#!/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()

yang keluaran:

[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]
paxdiablo
sumber
ini memberi saya hasil yang aneh. untuk p dalam potongan (kisaran (54), 3): print len ​​(p) mengembalikan 18, 18, 51 ...
Tetap, itu, itu hasil akhir.
paxdiablo
lihat juga solition at link
Jakob Kroeker
Ini adalah jawaban yang paling berguna untuk pertimbangan praktis. Terima kasih!
mVChr
Ketika saya menggunakan ini, melakukan for x in chunks(mylist,num): print x, saya mendapatkan potongan yang diinginkan, tetapi di antara mereka saya mendapatkan daftar kosong. Ada yang tahu kenapa? Yaitu, saya mendapatkan banyak [], satu demi satu potongan.
synaptik
12

Jika Anda membagi nelemen menjadi kpotongan yang kasar, Anda dapat membuat n % kpotongan 1 elemen lebih besar dari potongan lainnya untuk mendistribusikan elemen ekstra.

Kode berikut akan memberi Anda panjang untuk potongan:

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

Contoh: n=11, k=3menghasilkan[4, 4, 3]

Anda kemudian dapat dengan mudah menghitung mulai untuk potongan-potongan:

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

Contoh: n=11, k=3menghasilkan[0, 4, 8]

Menggunakan i+1potongan th sebagai batas kita mendapatkan bahwa ipotongan daftar ldengan len nadalah

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

Sebagai langkah terakhir, buat daftar dari semua bidak menggunakan pemahaman daftar:

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

Contoh: n=11, k=3, l=range(n)menghasilkan[range(0, 4), range(4, 8), range(8, 11)]

MaPePeR
sumber
6

Ini akan melakukan pemisahan dengan satu ekspresi:

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

Daftar dalam contoh ini memiliki ukuran 18 dan dibagi menjadi 5 bagian. Ukuran bagian berbeda tidak lebih dari satu elemen.

bitagoras
sumber
6

Lihat more_itertools.divide:

n = 2

[list(x) for x in mit.divide(n, range(5, 11))]
# [[5, 6, 7], [8, 9, 10]]

[list(x) for x in mit.divide(n, range(5, 12))]
# [[5, 6, 7, 8], [9, 10, 11]]

Instal via > pip install more_itertools.

pylang
sumber
4

Ini adalah salah satu yang menambahkan Noneuntuk membuat daftar panjangnya sama

>>> 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)]
John La Rooy
sumber
4

Ini solusinya:

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

Menghasilkan

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

Berikut adalah generator yang dapat menangani sejumlah bilangan positif (bilangan bulat). Jika jumlah chunk lebih besar dari panjang daftar input, beberapa chunk akan kosong. Algoritma ini bergantian antara potongan pendek dan panjang daripada memisahkan mereka.

Saya juga menyertakan beberapa kode untuk menguji ragged_chunksfungsi.

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

Kita dapat membuat ini sedikit lebih efisien dengan mengekspor perkalian ke dalam rangepanggilan, tetapi saya pikir versi sebelumnya lebih mudah dibaca (dan KERING).

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
PM 2Ring
sumber
3

Lihatlah numpy.split :

>>> a = numpy.array([1,2,3,4])
>>> numpy.split(a, 2)
[array([1, 2]), array([3, 4])]
dalloliogm
sumber
5
Dan numpy.array_split () bahkan lebih memadai karena kira-kira terbagi.
Yariv
11
Ini tidak berfungsi jika ukuran array tidak dapat dibagi dengan jumlah split.
Dan
1
Ini adalah jawaban yang salah, solusi Anda mengembalikan daftar ndarrays, bukan daftar daftar
Chłop Z Lasu
3

Implementasi menggunakan metode numpy.linspace.

Cukup tentukan jumlah bagian yang Anda inginkan untuk dibagi array. Divisi akan berukuran hampir sama.

Contoh:

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

Memberi:

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])]
amit12690
sumber
3

Solusi saya, mudah dimengerti

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

Dan satu kalimat terpendek pada halaman ini (ditulis oleh gadis saya)

def split(l, n):
    return [l[int(i*len(l)/n):int((i+1)*len(l)/n-1)] for i in range(n)]
Chłop Z Lasu
sumber
FYI: One-liner Anda rusak, menghasilkan hasil yang salah. Yang lain bekerja dengan indah.
Paulo Freitas
2

Menggunakan pemahaman daftar:

def divide_list_to_chunks(list_, n):
    return [list_[start::n] for start in range(n)]
liscju
sumber
Ini tidak membahas masalah membuat semua potongan bahkan.
SuperBiasedMan
0

Cara lain akan menjadi seperti ini, ide di sini adalah menggunakan kerapu, tapi singkirkan None. Dalam hal ini kita akan memiliki semua 'small_parts' terbentuk dari elemen di bagian pertama daftar, dan 'large_parts' dari bagian akhir daftar. Panjang 'bagian yang lebih besar' adalah len (small_parts) + 1. Kita perlu menganggap x sebagai dua sub-bagian yang berbeda.

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

Cara saya mengaturnya mengembalikan daftar tuple:

>>> 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)]
>>> 
Akavall
sumber
0

Berikut varian lain yang menyebarkan elemen-elemen "tersisa" secara merata di antara semua chunks, satu per satu hingga tidak ada yang tersisa. Dalam implementasi ini, potongan yang lebih besar terjadi pada awal proses.

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

Misalnya, hasilkan 4 bongkahan dari daftar 14 elemen:

>>> 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]
jreyes
sumber
0

Sama dengan jawaban pekerjaan , tetapi memperhitungkan daftar akun dengan ukuran lebih kecil dari jumlah chuncks.

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

jika n (jumlah chunks) adalah 7 dan lst (daftar untuk membagi) adalah [1, 2, 3] chunks adalah [[0], [1], [2]] bukan [[0], [1] ], [2], [], [], [], []]

Ilya Tuvschev
sumber
0

Anda juga bisa menggunakan:

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]]
Carlos del Ojo
sumber
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]

Contoh:

l = [a for a in range(97)] harus terdiri dari 10 bagian, masing-masing memiliki 9 elemen kecuali yang terakhir.

Keluaran:

[[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]]
emremrah
sumber
0

Katakanlah Anda ingin membagi daftar [1, 2, 3, 4, 5, 6, 7, 8] menjadi 3 daftar elemen

seperti [[1,2,3], [4, 5, 6], [7, 8]] , di mana jika elemen yang tersisa yang tersisa kurang dari 3, mereka dikelompokkan bersama.

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)

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

Di mana panjang satu bagian adalah 3. Ganti 3 dengan ukuran potongan Anda sendiri.

Ali Sajjad
sumber
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)
Bbake Waikhom
sumber
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

inilah versi saya (terinspirasi dari Max)

Solal Baudoin
sumber
-1

Membulatkan ruang ganti dan menggunakannya sebagai indeks adalah solusi yang lebih mudah daripada apa yang diusulkan amit12690.

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
galliwuzz
sumber
-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

Dipilih dari tautan ini , dan inilah yang membantu saya. Saya memiliki daftar yang telah ditentukan.

swateek
sumber
-1

katakanlah Anda ingin dibagi menjadi 5 bagian:

p1, p2, p3, p4, p5 = np.split(df, 5)
Danil
sumber
4
Ini tidak memberikan jawaban untuk pertanyaan, misalnya bagaimana Anda menulisnya jika Anda tidak tahu sebelumnya bahwa Anda ingin membaginya menjadi lima bagian. Juga, Anda (saya kira) menganggap numpy dan mungkin dataframe panda. OP bertanya tentang daftar generik.
NickD
-1

Saya sendiri sudah menulis kode dalam hal ini:

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

divide_ports (1, 10, 9) akan kembali

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

kode ini berfungsi untuk saya (kompatibel dengan Python3):

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

contoh (untuk tipe bytearray , tetapi berfungsi juga untuk daftar s):

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')]
grafi71
sumber
-1

Yang ini menyediakan potongan panjang <= 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)]

sebagai contoh

>>> 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]]
Anthony Manning-Franklin
sumber
-1

Saya mencoba sebagian besar solusi, tetapi mereka tidak berfungsi untuk kasus saya, jadi saya membuat fungsi baru yang berfungsi untuk sebagian besar kasus dan untuk semua jenis array:

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
Polo Ângelo
sumber