แยกรายการออกเป็นส่วนต่าง ๆ ที่มีความยาวเท่ากันโดยประมาณ


150

เป็นวิธีที่ดีที่สุดในการแบ่งรายการออกเป็นส่วนเท่ากันคืออะไร ตัวอย่างเช่นหากรายการมี 7 องค์ประกอบและแบ่งออกเป็น 2 ส่วนเราต้องการรับ 3 องค์ประกอบในส่วนหนึ่งส่วนอื่น ๆ ควรมีองค์ประกอบ 4 รายการ

ฉันกำลังมองหาบางอย่างeven_split(L, n)ที่แตกLออกเป็นnส่วน ๆ

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

รหัสข้างต้นให้ชิ้นส่วนจำนวน 3 ชิ้นแทนที่จะเป็น 3 ชิ้น ฉันสามารถแปลง (ทำซ้ำสิ่งนี้และรับองค์ประกอบแรกของแต่ละคอลัมน์เรียกส่วนนั้นจากนั้นนำส่วนที่สองมาใส่ในส่วนที่สอง ฯลฯ ) แต่นั่นเป็นการทำลายการเรียงลำดับของรายการ

คำตอบ:


64

รหัสนี้ใช้งานไม่ได้เนื่องจากข้อผิดพลาดในการปัดเศษ อย่าใช้มัน !!!

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

นี่คือสิ่งที่สามารถใช้งานได้:

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

การทดสอบ:

>>> 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
ตัวอย่างของคุณจะไม่ทำงานสำหรับ>>> chunkIt(range(8), 6)=>[[0], [1], [2, 3], [4], [5], [6], [7]]
nopper

1
@nopper ฉันเพิ่มเงื่อนไข "if num == 1:" เพื่อจัดการกับตัวพิมพ์ขอบนั้น
paulie4

24
ผู้เข้าชมใหม่: โปรดอย่าใช้หรือลงรหัสนี้มันเสีย เช่นchunkIt(range(10), 9)ควรคืน 9 ส่วน แต่ไม่ได้
Wim

3
กระทู้ความคิดเห็นนี้สับสนจริงๆเนื่องจากคำตอบถูกแก้ไขหลายครั้ง นี่เป็นคำตอบที่ดีใช่ไหม ไม่ใช่คำตอบที่ดีใช่ไหม
conchoecia

6
@conchoecia ไม่ใช่คำตอบที่ดีเลยให้เลื่อนลง นี่เป็นเพียงการแก้ไขครั้งเดียวและมันเป็นเพียงการแก้ไขเล็กน้อย (เยื้องพื้นที่ 2 เปลี่ยนเป็น 4) น่าเสียดายที่ OP "user248237dfsf" ยังไม่เคยเห็นในเว็บไซต์มานานกว่า 3 ปีดังนั้นจึงมีความหวังเพียงเล็กน้อยในการได้รับคำตอบที่เปลี่ยนไป
Wim

182

คุณสามารถเขียนมันค่อนข้างเรียบง่ายเป็นตัวสร้างรายการ:

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

ตัวอย่าง:

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

แทรกn = min(n, len(a)) # don't create empty bucketsในบรรทัดที่ 1 เพื่อหลีกเลี่ยงการสร้างบุ้งกี๋ที่ว่างเปล่าในสถานการณ์เช่นlist(split(range(X, Y)))ที่X < Y
abanana

การเห็นว่าฉันไม่สามารถแก้ไขความคิดเห็นของฉัน - ฉันควรเพิ่มว่าการแก้ไขก่อนหน้านี้ของฉันอาจเพิ่มการหารด้วยศูนย์ข้อผิดพลาดหากรายการว่างเปล่าดังนั้นจำเป็นต้องมีการควบคุมจากภายนอกหรือเพิ่มไปยังโซลูชัน
abanana

4
จากคำตอบ N ทั้งหมดบน SO นี่เป็นสิ่งเดียวเท่านั้นที่ผ่านการทดสอบทั้งหมดของฉัน GJ!
avishayp

2
stackoverflow.com/a/37414115/210971ใช้วิธีการเดียวกัน แต่ใช้กับรายการที่ว่างเปล่าและตัวแยกการแบ่ง 0
LookAheadAtYourTypes

สวย! นอกจากนี้ยังสามารถใช้ n ทำงานเป็น batch_size ได้โดยการสลับ k และ n ในคำสั่ง return :)
23919

162

นี่คือraison d'êtreสำหรับ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]

* เครดิตให้กับZero Piraeusในห้อง 6


1
มี*ไว้printเพื่ออะไร
yuqli

2
เฮ้ @yuqli มันแปลงรายการของสิ่งที่เป็นข้อโต้แย้งของแต่ละบุคคลเพื่อฟังก์ชั่น ลองprint(L)และ `พิมพ์ (* L) ดูstackoverflow.com/a/36908/2184122หรือค้นหา "python use of asterisk"
Robert Lugg

121

ตราบใดที่คุณไม่ต้องการอะไรที่โง่เหมือนชิ้นต่อเนื่อง:

>>> 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
ฉันจะไม่พูดชิ้นที่ต่อเนื่องมันโง่ บางทีคุณอาจต้องการจัดเรียงชิ้นข้อมูล (เช่น chunk [0] <chunk [1]) เป็นต้น
tixxit

1
ฉันถูกหลอก. แต่ถ้าคุณไม่ใส่ใจจริงๆวิธีนี้มีความเข้าใจในรายการดีและรัดกุม
งาน

3
นี่เป็นการห้อยด้วยn
smci

8
ส่งผลลัพธ์นี้ไปที่ 'zip' จะให้รายการสั่งซื้อของคุณ: zip(*chunkify(range(13), 3))results in[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11)]
gens

2
โซลูชั่นนี้ใช้งานได้ดีจนกว่าคุณจะต้องเรียงลำดับรายการที่เหมือนกัน
s7anley

18

การเปลี่ยนรหัสเพื่อให้ได้nชิ้นแทนที่จะเป็น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()

ซึ่งจะช่วยให้:

[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 องค์ประกอบจะดีกว่า (19,19,18) ในขณะที่สิ่งนี้ให้ (18,18,20)

คุณสามารถได้ผลลัพธ์ที่สมดุลมากขึ้นด้วยรหัสต่อไปนี้:

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

ผลลัพธ์ใด:

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

สิ่งนี้ให้ผลลัพธ์ที่แปลกแก่ฉัน สำหรับ p ในกลุ่มชิ้น (ช่วง (54), 3): print len ​​(p) ส่งคืน 18, 18, 51 ...

คงที่มันเป็นผลผลิตขั้นสุดท้าย
paxdiablo

ดู solation ที่ลิงค์
Jakob Kroeker

นี่เป็นคำตอบที่มีประโยชน์ที่สุดสำหรับการพิจารณาในทางปฏิบัติ ขอบคุณ!
mVChr

เมื่อฉันใช้สิ่งนี้การทำfor x in chunks(mylist,num): print xฉันได้รับชิ้นที่ต้องการ แต่ระหว่างนั้นฉันจะได้รายการที่ว่างเปล่า มีความคิดอะไรไหม นั่นคือฉันได้รับมากมาย[]หลังจากแต่ละก้อน
synaptik

12

หากคุณแบ่งnองค์ประกอบออกเป็นkส่วน ๆ คุณสามารถทำให้n % kองค์ประกอบหนึ่งมีขนาดใหญ่กว่าชิ้นส่วนอื่น ๆ เพื่อกระจายองค์ประกอบพิเศษได้

รหัสต่อไปนี้จะให้ความยาวของชิ้นส่วน:

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

ตัวอย่าง: n=11, k=3ผลลัพธ์[4, 4, 3]

จากนั้นคุณสามารถคำนวณจุดเริ่มต้นของชิ้นได้อย่างง่ายดาย:

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

ตัวอย่าง: n=11, k=3ผลลัพธ์[0, 4, 8]

การใช้อันที่สองi+1เป็นขอบเขตที่เราได้รับว่าอันที่iของรายการlกับ len nคือ

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

เป็นขั้นตอนสุดท้ายสร้างรายการจากกลุ่มทั้งหมดโดยใช้ list comprehension:

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

ตัวอย่าง: n=11, k=3, l=range(n)ผลลัพธ์[range(0, 4), range(4, 8), range(8, 11)]


6

สิ่งนี้จะทำการแยกโดยนิพจน์เดียว:

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

รายการในตัวอย่างนี้มีขนาด 18 และแบ่งออกเป็น 5 ส่วน ขนาดของชิ้นส่วนต่างกันไม่เกินหนึ่งองค์ประกอบ



4

นี่คือสิ่งที่เพิ่มขึ้นNoneเพื่อทำให้รายการมีความยาวเท่ากัน

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

นี่คือทางออกของฉัน:

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

ผลิต

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

4

นี่คือเครื่องกำเนิดไฟฟ้าที่สามารถจัดการจำนวนชิ้นบวก (จำนวนเต็ม) ได้ หากจำนวนชิ้นมากกว่าความยาวของรายการที่ป้อนบางชิ้นจะว่างเปล่า อัลกอริทึมนี้สลับไปมาระหว่างชิ้นส่วนสั้นและชิ้นยาวแทนที่จะแยกพวกมันออก

ฉันได้รวมรหัสบางอย่างสำหรับการทดสอบragged_chunksฟังก์ชั่น

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

เราสามารถทำให้สิ่งนี้มีประสิทธิภาพมากขึ้นเล็กน้อยโดยการส่งออกการคูณไปยังการrangeโทร แต่ฉันคิดว่ารุ่นก่อนหน้านี้สามารถอ่านได้มากขึ้น (และ 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

ดูที่numpy.split :

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

5
และ numpy.array_split () ยิ่งเพียงพอเพราะมันแยกกันอย่างคร่าว ๆ
Yariv

11
วิธีนี้ใช้ไม่ได้หากขนาดอาร์เรย์ไม่สามารถหารด้วยจำนวนการแบ่งได้
Dan

1
นี่คือคำตอบที่ผิดวิธีแก้ปัญหาของคุณจะส่งคืนรายการของ ndarrays ไม่ใช่รายการของรายการ
Chłop Z Lasu

3

การใช้งานโดยใช้วิธี numpy.linspace

เพียงระบุจำนวนชิ้นส่วนที่คุณต้องการให้อาร์เรย์หารด้วยส่วนจะมีขนาดใกล้เคียงกัน

ตัวอย่าง:

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

ให้:

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

ทางออกของฉันเข้าใจง่าย

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

และสั้นที่สุดหนึ่งซับในหน้านี้ (เขียนโดยสาวของฉัน)

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

FYI: สายการบินเดียวของคุณเสียและให้ผลที่ผิด อีกอันหนึ่งทำงานได้อย่างสวยงาม
เปาโล Freitas

2

ใช้รายการเข้าใจ:

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

สิ่งนี้ไม่ได้แก้ไขปัญหาในการทำให้ชิ้นส่วนทั้งหมดเท่ากัน
SuperBiasedMan

0

อีกวิธีหนึ่งที่จะเป็นสิ่งที่เช่นนี้ความคิดที่นี่คือการใช้ปลาเก๋า Noneแต่กำจัด ในกรณีนี้เราจะมี 'small_parts' ทั้งหมดเกิดขึ้นจากองค์ประกอบที่ส่วนแรกของรายการและ 'large_parts' จากส่วนหลังของรายการ ความยาวของ 'ชิ้นส่วนที่ใหญ่กว่า' คือ len (small_parts) + 1 เราต้องพิจารณาว่า x เป็นชิ้นส่วนย่อยที่แตกต่างกันสองส่วน

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

วิธีที่ฉันตั้งค่าให้ส่งคืนรายการของ tuples:

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

นี่คืออีกหนึ่งตัวแปรที่กระจายองค์ประกอบ "ที่เหลือ" อย่างสม่ำเสมอในกลุ่มชิ้นทั้งหมดทีละตัวจนกว่าจะไม่มีใครเหลือ ในการใช้งานนี้ชิ้นใหญ่ขึ้นเกิดขึ้นที่จุดเริ่มต้นกระบวนการ

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

ตัวอย่างเช่นสร้าง 4 ชิ้นจากรายการ 14 องค์ประกอบ:

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

เช่นเดียวกับคำตอบของงานแต่คำนึงถึงรายการบัญชีที่มีขนาดเล็กกว่าจำนวนช่องว่าง

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

ถ้า n (จำนวนชิ้น) คือ 7 และ lst (รายการแบ่ง) คือ [1, 2, 3] ชิ้นนั้นคือ [[0], [1], [2]] แทน [[0], [1] ], [2], [], [], [], []]


0

คุณสามารถใช้:

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]

ตัวอย่าง:

l = [a for a in range(97)] ควรประกอบด้วย 10 ส่วนแต่ละองค์ประกอบมี 9 องค์ประกอบยกเว้นส่วนสุดท้าย

เอาท์พุท:

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

สมมติว่าคุณต้องการแยกรายการ[1, 2, 3, 4, 5, 6, 7, 8]เป็น 3 รายการองค์ประกอบ

เช่น[[1,2,3], [4, 5, 6], [7, 8]]ซึ่งหากองค์ประกอบสุดท้ายที่เหลืออยู่มีค่าน้อยกว่า 3 พวกมันจะถูกจัดกลุ่มเข้าด้วยกัน

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)

เอาต์พุต: [[1,2,3], [4, 5, 6], [7, 8]]

เมื่อความยาวของส่วนหนึ่งเท่ากับ 3 แทนที่ 3 ด้วยขนาดก้อนของคุณเอง


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

นี่คือเวอร์ชั่นของฉัน (แรงบันดาลใจจาก Max's)


-1

การปัดเศษ linspace และใช้เป็นดัชนีเป็นวิธีแก้ปัญหาที่ง่ายกว่าที่ 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

-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

เลือกจากลิงค์นี้และนี่คือสิ่งที่ช่วยฉัน ฉันมีรายการที่กำหนดไว้ล่วงหน้า


-1

บอกว่าคุณต้องการแบ่งออกเป็น 5 ส่วน:

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

4
สิ่งนี้ไม่ได้ให้คำตอบสำหรับคำถามเช่นคุณจะเขียนมันอย่างไรถ้าคุณไม่ทราบล่วงหน้าว่าคุณต้องการแยกเป็นห้าชิ้น นอกจากนี้คุณเป็น (ฉันคาดเดา) สมมติว่ามีจำนวนมากและอาจเป็นดาต้าดาต้าแพนด้า OP กำลังถามเกี่ยวกับรายการทั่วไป
NickD

-1

ฉันเขียนโค้ดในกรณีนี้ด้วยตัวเอง:

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) จะกลับมา

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

-1

รหัสนี้ใช้งานได้สำหรับฉัน (รองรับ 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))]

ตัวอย่าง (สำหรับประเภทbytearrayแต่ใช้ได้กับlist 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')]

-1

อันนี้ให้ความยาวของชิ้น <= 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)]

ตัวอย่างเช่น

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

ฉันได้ลองใช้วิธีแก้ปัญหาส่วนใหญ่แล้ว แต่มันไม่ได้ผลกับเคสของฉันดังนั้นฉันจึงสร้างฟังก์ชั่นใหม่ที่ใช้ได้กับเคสส่วนใหญ่และอาเรย์ทุกประเภท:

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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.