आप समान रूप से आकार की सूची में कैसे विभाजित करते हैं?


2263

मेरे पास मनमानी लंबाई की एक सूची है, और मुझे इसे समान आकार के टुकड़ों में विभाजित करने और उस पर काम करने की आवश्यकता है। ऐसा करने के लिए कुछ स्पष्ट तरीके हैं, जैसे एक काउंटर और दो सूचियाँ रखना, और जब दूसरी सूची भर जाती है, तो इसे पहली सूची में जोड़ें और दूसरी सूची को डेटा के अगले दौर के लिए खाली कर दें, लेकिन यह संभवतः बेहद महंगी है।

मैं सोच रहा था कि अगर किसी के पास किसी भी लंबाई की सूची के लिए एक अच्छा समाधान था, उदाहरण के लिए जनरेटर का उपयोग करना।

मैं कुछ उपयोगी की तलाश में था, itertoolsलेकिन मुझे स्पष्ट रूप से उपयोगी कुछ भी नहीं मिला। हालांकि यह याद किया होगा।

संबंधित प्रश्न: चूजों में सूची पर पुनरावृति करने का सबसे "पायथोनिक" तरीका क्या है?


1
नया उत्तर पोस्ट करने से पहले, विचार करें कि इस प्रश्न के लिए पहले से ही 60+ उत्तर हैं। कृपया, सुनिश्चित करें कि आपका उत्तर उन सूचनाओं का योगदान करता है जो मौजूदा उत्तरों में नहीं हैं।
जन्निक्स

कि एक मनमाने ढंग से छोटे अंतिम हिस्सा बचना चाहते हैं उपयोगकर्ताओं के लिए, से अधिक पर देखने के विभाजन लगभग समान लंबाई के एन भागों में एक सूची
विम

जवाबों:


3145

यहां एक जेनरेटर है जो आपके द्वारा चाहा गया पैदावार देता है:

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

import pprint
pprint.pprint(list(chunks(range(10, 75), 10)))
[[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]]

यदि आप पायथन 2 का उपयोग कर रहे हैं, तो आपको xrange()इसके स्थान पर उपयोग करना चाहिए range():

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

इसके अलावा, आप केवल फ़ंक्शन लिखने के बजाय सूची समझ का उपयोग कर सकते हैं, हालांकि यह नामांकित कार्यों में इस तरह के संचालन को एन्क्रिप्ट करने के लिए एक अच्छा विचार है ताकि आपके कोड को समझना आसान हो। अजगर 3:

[lst[i:i + n] for i in range(0, len(lst), n)]

पायथन 2 संस्करण:

[lst[i:i + n] for i in xrange(0, len(lst), n)]

71
यदि हम सूची की लंबाई नहीं बता सकते तो क्या होता है? Itertools.repeat ([1, 2, 3]) पर इसका प्रयास करें, जैसे
jespern

47
यह सवाल का एक दिलचस्प विस्तार है, लेकिन मूल प्रश्न स्पष्ट रूप से एक सूची पर काम करने के बारे में पूछा गया है।
नेड बैचेल्ड 13

32
इस कार्यों की जरूरत है लानत मानक पुस्तकालय में होना
dgan

6
@ कैलीमो: आप क्या सुझाव देते हैं? मैं आपको 47 तत्वों के साथ एक सूची सौंपता हूं। आप इसे "समान आकार के विखंडू" में कैसे विभाजित करना चाहेंगे? ओपी ने जवाब स्वीकार किया, इसलिए वे स्पष्ट रूप से पिछले अलग-अलग आकार के चंक के साथ ठीक हैं। शायद अंग्रेजी वाक्यांश अभेद्य है?
नेड बैचेल्ड

8
कृपया अपने चर l का नाम न दें, यह ठीक 1 जैसा दिखता है और भ्रमित कर रहा है। लोग आपके कोड को कॉपी कर रहे हैं और सोचते हैं कि यह ठीक है।
यासेन

555

यदि आप कुछ सुपर सरल चाहते हैं:

def chunks(l, n):
    n = max(1, n)
    return (l[i:i+n] for i in range(0, len(l), n))

xrange()इसके बजाय range()अजगर 2.x के मामले में उपयोग करें


6
या (यदि हम इस विशेष समारोह के विभिन्न निरूपण कर रहे हैं) तो आप लैम्बडा x, y: [x [i: i + y] के लिए i को रेंज में (0, len (x), y) के माध्यम से एक लंबो फ़ंक्शन को परिभाषित कर सकते हैं। ] हो गया। मुझे यह सूची-समझ विधि पसंद है!
जेपी

4
वापसी के बाद वहाँ होना चाहिए, नहीं (
alwbtc

2
"सुपर सरल" का अर्थ है अनंत लूपों को डिबग करना नहीं - के लिए यश max()
बॉब स्टीन

इस समाधान के बारे में कुछ भी सरल नहीं है
mit

1
@ Nhoj_Gonk ओह, यह एक अनंत लूप नहीं है, लेकिन विखंडू (एल, 0) अधिकतम के बिना एक वैल्यू एड्रार बढ़ाएगा ()। इसके बजाय, अधिकतम () 1 से कम कुछ भी 1 में बदल जाता है
बॉब स्टीन

294

सीधे (पुराने) पायथन प्रलेखन (itertools के लिए व्यंजनों) से:

from itertools import izip, chain, repeat

def grouper(n, iterable, padvalue=None):
    "grouper(3, 'abcdefg', 'x') --> ('a','b','c'), ('d','e','f'), ('g','x','x')"
    return izip(*[chain(iterable, repeat(padvalue, n-1))]*n)

JFSebastian द्वारा सुझाया गया वर्तमान संस्करण:

#from itertools import izip_longest as zip_longest # for Python 2.x
from itertools import zip_longest # for Python 3.x
#from six.moves import zip_longest # for both (uses the six compat library)

def grouper(n, iterable, padvalue=None):
    "grouper(3, 'abcdefg', 'x') --> ('a','b','c'), ('d','e','f'), ('g','x','x')"
    return zip_longest(*[iter(iterable)]*n, fillvalue=padvalue)

मुझे लगता है कि गुइडो की टाइम मशीन काम करती है- काम करेगी-काम करेगी-काम करेगी-फिर से काम कर रही थी।

ये समाधान काम करते हैं क्योंकि [iter(iterable)]*n(या पहले के संस्करण में समतुल्य) एक पुनरावृत्ति बनाता है, nसूची में बार - बार। izip_longestतब प्रभावी रूप से "प्रत्येक" पुनरावृत्त का एक गोल-रॉबिन करता है; क्योंकि यह एक ही पुनरावृत्ति है, यह इस तरह के प्रत्येक कॉल से उन्नत होता है, जिसके परिणामस्वरूप प्रत्येक ऐसे ज़िप-राउंड्रोबिन nआइटम का एक टपल पैदा करते हैं ।


@ninjagecko: list(grouper(3, range(10)))रिटर्न [(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, None, None)], और सभी tuples लंबाई के हैं 3. कृपया अपनी टिप्पणी पर विस्तृत करें क्योंकि मैं इसे समझ नहीं सकता; आप किसी चीज़ को क्या कहते हैं और आप इसे कैसे परिभाषित करते हैं कि यह 3 का गुणक है "आपकी चीज़ के 3 से अधिक होने की उम्मीद करना"? पहले ही, आपका बहुत धन्यवाद।
tzot

14
इसे अपवित्र किया गया क्योंकि यह जनरेटर (कोई लेन) पर काम करता है और आम तौर पर तेजी से चलने वाले इटर्टूल मॉड्यूल का उपयोग करता है।
माइकल डिलन

88
फैंसी itertoolsकार्यात्मक दृष्टिकोण का एक उत्कृष्ट उदाहरण कुछ अपठित कीचड़ को बाहर निकालता है, जब एक सरल और भोले शुद्ध अजगर कार्यान्वयन की तुलना में
wim

15
@wim यह देखते हुए कि यह उत्तर पायथन डॉक्यूमेंटेशन के स्निपेट के रूप में शुरू हुआ है, मैं आपको सुझाव दूंगा कि आप bugs.pyzon.org पर एक समस्या खोलें ।
tzot

1
@pedrosaurio अगर l==[1, 2, 3]इसके f(*l)बराबर है f(1, 2, 3)। देखें कि प्रश्न और आधिकारिक दस्तावेज
tzot 8

224

मुझे पता है कि यह पुराना है लेकिन अभी तक किसी ने उल्लेख नहीं किया है numpy.array_split:

import numpy as np

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

12
इससे आप कुल संख्या को चुन सकते हैं, न कि तत्वों की संख्या प्रति हिस्सा।
FizxMike

6
आप गणित स्वयं कर सकते हैं। यदि आपके पास 10 तत्व हैं, तो आप उन्हें 2, 5 तत्वों के विखंडू या पाँचों तत्वों के समूह में बाँट सकते हैं
Moj

24
+1 यह मेरा पसंदीदा समाधान है, क्योंकि यह सरणी को समान रूप से सरणियों में विभाजित करता है , जबकि अन्य समाधान नहीं हैं (अन्य सभी समाधानों में, जिन्हें मैंने देखा, अंतिम सरणी मनमाने ढंग से छोटी हो सकती है)।
मिनीक्वार

@MiniQuark लेकिन यह क्या करता है जब ब्लॉक की संख्या मूल सरणी आकार का कारक नहीं है?
बाल्ड्रिक

1
@Baldrickk यदि आप N तत्वों को K विखंडन में विभाजित करते हैं, तो पहले N% K विखंडन में N // K + 1 तत्व होंगे, और शेष में N // K तत्व होंगे। उदाहरण के लिए, यदि आप एक सरणी को 108 तत्वों से विभाजित करते हैं, जिसमें 5 भाग होते हैं, तो पहले 108% 5 = 3 भाग में 108 // 5 + 1 = 22 तत्व होंगे, और बाकी हिस्सों में 108 // 5 = 21 होगा तत्वों।
मिनीक्वार्क

147

मैं हैरान कोई नहीं का उपयोग कर के बारे में सोचा गया है iterएस ' दो तर्क प्रपत्र :

from itertools import islice

def chunk(it, size):
    it = iter(it)
    return iter(lambda: tuple(islice(it, size)), ())

डेमो:

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

यह किसी भी पुनरावृत्ति के साथ काम करता है और उत्पादन का उत्पादन करता है। यह पुनरावृत्तियों के बजाय ट्यूपल लौटाता है, लेकिन मुझे लगता है कि इसके पास एक निश्चित लालित्य है। यह पैड भी नहीं करता है; यदि आप गद्दी चाहते हैं, तो ऊपर दी गई एक साधारण भिन्नता पर्याप्त होगी:

from itertools import islice, chain, repeat

def chunk_pad(it, size, padval=None):
    it = chain(iter(it), repeat(padval))
    return iter(lambda: tuple(islice(it, size)), (padval,) * size)

डेमो:

>>> list(chunk_pad(range(14), 3))
[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11), (12, 13, None)]
>>> list(chunk_pad(range(14), 3, 'a'))
[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11), (12, 13, 'a')]

जैसा izip_longestआधारित समाधान, ऊपर हमेशा पैड। जहाँ तक मुझे पता है, वैकल्पिक रूप से पैड्स के फंक्शन के लिए कोई एक या दो-लाइन इटर्टूलस नुस्खा नहीं है । उपरोक्त दो दृष्टिकोणों को मिलाकर, यह बहुत करीब आता है:

_no_padding = object()

def chunk(it, size, padval=_no_padding):
    if padval == _no_padding:
        it = iter(it)
        sentinel = ()
    else:
        it = chain(iter(it), repeat(padval))
        sentinel = (padval,) * size
    return iter(lambda: tuple(islice(it, size)), sentinel)

डेमो:

>>> list(chunk(range(14), 3))
[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11), (12, 13)]
>>> list(chunk(range(14), 3, None))
[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11), (12, 13, None)]
>>> list(chunk(range(14), 3, 'a'))
[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11), (12, 13, 'a')]

मेरा मानना ​​है कि यह सबसे कम समय का प्रस्ताव है जो वैकल्पिक पैडिंग प्रदान करता है।

जैसा कि टॉमस गैंडर ने देखा , यदि वे पैड मानों के लंबे अनुक्रम का सामना करते हैं, तो दो पैडिंग चंकर अप्रत्याशित रूप से बंद हो जाएंगे। यहाँ एक अंतिम भिन्नता है जो उचित तरीके से उस समस्या को हल करती है:

_no_padding = object()
def chunk(it, size, padval=_no_padding):
    it = iter(it)
    chunker = iter(lambda: tuple(islice(it, size)), ())
    if padval == _no_padding:
        yield from chunker
    else:
        for ch in chunker:
            yield ch if len(ch) == size else ch + (padval,) * (size - len(ch))

डेमो:

>>> list(chunk([1, 2, (), (), 5], 2))
[(1, 2), ((), ()), (5,)]
>>> list(chunk([1, 2, None, None, 5], 2, None))
[(1, 2), (None, None), (5, None)]

7
अद्भुत, आपका सरल संस्करण मेरा पसंदीदा है। अन्य लोग भी मूल islice(it, size)अभिव्यक्ति के साथ आए और इसे (जैसे मैंने किया था) एक पाश निर्माण में अंतःस्थापित किया। केवल आपने दो-तर्क संस्करण के बारे में सोचा iter()(मैं पूरी तरह से अनजान था), जो इसे सुपर-एलिगेंट बनाता है (और शायद सबसे प्रदर्शन-प्रभावी)। मुझे नहीं पता था कि iterसेंटिनल दिए जाने पर 0-तर्क फ़ंक्शन में परिवर्तन करने वाला पहला तर्क । आप विखंडू के एक (पॉट। अनंत) इट्रेटर लौटाते हैं, इनपुट के रूप में एक (पॉट। अनंत) पुनरावृत्त का उपयोग कर सकते हैं, कोई len()और कोई सरणी स्लाइस नहीं है। बहुत बढ़िया!
थॉमस

1
यही कारण है कि मैं सिर्फ शीर्ष जोड़ी को स्कैन करने के बजाय उत्तरों के माध्यम से पढ़ता हूं। मेरे मामले में वैकल्पिक पैडिंग एक आवश्यकता थी, और मैंने भी पुनरावृति के दो-तर्क रूप के बारे में सीखा।
केर

मैंने इसे बढ़ा दिया, लेकिन फिर भी - चलो इसे ओवरहाइप न करें! सबसे पहले, लैम्ब्डा खराब हो सकता है ( itइट्रेटर पर धीमी गति से बंद करना । दूसरा, और सबसे अधिक आयात - आप समय से पहले समाप्त हो जाएगा यदि padvalवास्तव में आपके चलने योग्य में एक हिस्सा मौजूद है, और इसे संसाधित किया जाना चाहिए।
टॉमस गैंडर

@ टॉमसजैंडर, मैं आपका पहला बिंदु लेता हूं! यद्यपि मेरी समझ यह है कि लंबोदर किसी साधारण कार्य की तुलना में कोई धीमा नहीं है, निश्चित रूप से आप सही हैं कि फ़ंक्शन कॉल और क्लोजर लुक-अप इसे धीमा कर देगा। मुझे नहीं पता कि इसका सापेक्ष प्रदर्शन क्या होगा izip_longest, उदाहरण के लिए, उदाहरण के लिए - मुझे संदेह है कि यह एक जटिल व्यापार-बंद हो सकता है। लेकिन ... क्या padvalहर मुद्दे पर साझा किया गया मुद्दा यहां एक padvalपैरामीटर प्रदान नहीं करता है ?
प्रेषक

1
@ टोमसज़गैंडर, काफी निष्पक्ष! लेकिन इसे ठीक करने वाला संस्करण बनाना बहुत कठिन नहीं था। (यह भी ध्यान दें, बहुत पहले संस्करण, जो ()प्रहरी के रूप में उपयोग करता है , सही तरीके से काम करता है। ऐसा इसलिए है क्योंकि जब खाली होता है तो tuple(islice(it, size))पैदावार ()होती itहै।)
प्रेषक

93

यहाँ एक जनरेटर है जो मनमाने ढंग से चलने पर काम करता है:

def split_seq(iterable, size):
    it = iter(iterable)
    item = list(itertools.islice(it, size))
    while item:
        yield item
        item = list(itertools.islice(it, size))

उदाहरण:

>>> import pprint
>>> pprint.pprint(list(split_seq(xrange(75), 10)))
[[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]]

52
def chunk(input, size):
    return map(None, *([iter(input)] * size))

map(None, iter)बराबर होता है izip_longest(iter)
थॉमस अहले

1
@TomaszWysocki क्या आप अपने *सामने इटैलर टपल समझा सकते हैं ? संभवतः आपके उत्तर पाठ में, लेकिन मैंने देखा है कि *पहले पायथन में उस तरह से इस्तेमाल किया गया था। धन्यवाद!
TheJollySin

1
@theJollySin इस संदर्भ में, इसे स्पैट ऑपरेटर कहा जाता है। इसका उपयोग यहाँ बताया गया है - stackoverflow.com/questions/5917522/unzipping-and-the-operator
21

2
बंद करें लेकिन अंतिम चंक के पास इसे भरने के लिए कोई तत्व नहीं है। यह एक दोष हो भी सकता है और नहीं भी। हालांकि शांत पैटर्न।

48

सरल अभी तक सुरुचिपूर्ण

l = range(1, 1000)
print [l[x:x+10] for x in xrange(0, len(l), 10)]

या यदि आप पसंद करते हैं:

def chunks(l, n): return [l[x: x+n] for x in xrange(0, len(l), n)]
chunks(l, 10)

18
तुम एक अरबी संख्या की समानता में एक चर डब नहीं करोगे। कुछ फोंट में, 1और lअप्रभेद्य हैं। जैसे हैं 0और O। और कभी-कभी Iऔर भी 1
अल्फ

14
@ अन्य दोषपूर्ण फोंट। लोगों को ऐसे फोंट का उपयोग नहीं करना चाहिए। प्रोग्रामिंग के लिए नहीं, किसी चीज के लिए नहीं
जेरी बी

17
लैंबडास का उपयोग अनाम कार्यों के रूप में किया जाना है। उन्हें इस तरह इस्तेमाल करने का कोई मतलब नहीं है। इसके अलावा यह डिबगिंग को और अधिक कठिन बनाता है क्योंकि त्रुटि के मामले में ट्रेसबैक "<लैंबडा>" में "चंक्स" के बजाय रिपोर्ट करेगा। मेरी इच्छा है कि आप एक समस्या
पाएं

1
यह 0 होना चाहिए और 1 के अंदर 1 नहीं होना चाहिएprint [l[x:x+10] for x in xrange(1, len(l), 10)]
scottydelta

नोट: पायथन 3 उपयोगकर्ताओं के लिए उपयोग करें range
क्रिश्चियन डीन

40

अन्य उत्तरों की आलोचना यहां करें:

इन उत्तरों में से कोई भी समान रूप से आकार नहीं है, वे सभी एक रन चंक को अंत में छोड़ देते हैं, इसलिए वे पूरी तरह से संतुलित नहीं हैं। यदि आप काम को वितरित करने के लिए इन कार्यों का उपयोग कर रहे थे, तो आपने दूसरों के सामने एक अच्छी तरह से खत्म होने की संभावना के लिए बिल्ट-इन किया है, इसलिए यह कुछ भी नहीं करने के लिए बैठेगा, जबकि अन्य कड़ी मेहनत करते रहेंगे।

उदाहरण के लिए, वर्तमान शीर्ष उत्तर के साथ समाप्त होता है:

[60, 61, 62, 63, 64, 65, 66, 67, 68, 69],
[70, 71, 72, 73, 74]]

मैं अंत में उस रन से नफरत करता हूं!

अन्य, जैसे list(grouper(3, xrange(7))), और chunk(xrange(7), 3)दोनों वापस आते हैं [(0, 1, 2), (3, 4, 5), (6, None, None)]:। Noneकी बस padding रहे हैं, और नहीं बल्कि मेरी राय में असजीला। वे समान रूप से पुनरावृत्तियों को नहीं देख रहे हैं।

हम इन्हें बेहतर क्यों नहीं बाँट सकते?

मेरा समाधान

यहाँ एक संतुलित समाधान दिया गया है, जिसे मैंने उत्पादन में उपयोग किया है (नोट पायथन 3 में नोट के xrangeसाथrange ):

def baskets_from(items, maxbaskets=25):
    baskets = [[] for _ in xrange(maxbaskets)] # in Python 3 use range
    for i, item in enumerate(items):
        baskets[i % maxbaskets].append(item)
    return filter(None, baskets) 

और मैंने एक जनरेटर बनाया जो अगर आप इसे सूची में रखते हैं तो वही होता है:

def iter_baskets_from(items, maxbaskets=3):
    '''generates evenly balanced baskets from indexable iterable'''
    item_count = len(items)
    baskets = min(item_count, maxbaskets)
    for x_i in xrange(baskets):
        yield [items[y_i] for y_i in xrange(x_i, item_count, baskets)]

और अंत में, क्योंकि मैं देखता हूं कि उपरोक्त सभी कार्य एक सन्निहित क्रम में तत्व वापस करते हैं (जैसा कि उन्हें दिया गया था):

def iter_baskets_contiguous(items, maxbaskets=3, item_count=None):
    '''
    generates balanced baskets from iterable, contiguous contents
    provide item_count if providing a iterator that doesn't support len()
    '''
    item_count = item_count or len(items)
    baskets = min(item_count, maxbaskets)
    items = iter(items)
    floor = item_count // baskets 
    ceiling = floor + 1
    stepdown = item_count % baskets
    for x_i in xrange(baskets):
        length = ceiling if x_i < stepdown else floor
        yield [items.next() for _ in xrange(length)]

उत्पादन

उनका परीक्षण करने के लिए:

print(baskets_from(xrange(6), 8))
print(list(iter_baskets_from(xrange(6), 8)))
print(list(iter_baskets_contiguous(xrange(6), 8)))
print(baskets_from(xrange(22), 8))
print(list(iter_baskets_from(xrange(22), 8)))
print(list(iter_baskets_contiguous(xrange(22), 8)))
print(baskets_from('ABCDEFG', 3))
print(list(iter_baskets_from('ABCDEFG', 3)))
print(list(iter_baskets_contiguous('ABCDEFG', 3)))
print(baskets_from(xrange(26), 5))
print(list(iter_baskets_from(xrange(26), 5)))
print(list(iter_baskets_contiguous(xrange(26), 5)))

जो प्रिंट करता है:

[[0], [1], [2], [3], [4], [5]]
[[0], [1], [2], [3], [4], [5]]
[[0], [1], [2], [3], [4], [5]]
[[0, 8, 16], [1, 9, 17], [2, 10, 18], [3, 11, 19], [4, 12, 20], [5, 13, 21], [6, 14], [7, 15]]
[[0, 8, 16], [1, 9, 17], [2, 10, 18], [3, 11, 19], [4, 12, 20], [5, 13, 21], [6, 14], [7, 15]]
[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11], [12, 13, 14], [15, 16, 17], [18, 19], [20, 21]]
[['A', 'D', 'G'], ['B', 'E'], ['C', 'F']]
[['A', 'D', 'G'], ['B', 'E'], ['C', 'F']]
[['A', 'B', 'C'], ['D', 'E'], ['F', 'G']]
[[0, 5, 10, 15, 20, 25], [1, 6, 11, 16, 21], [2, 7, 12, 17, 22], [3, 8, 13, 18, 23], [4, 9, 14, 19, 24]]
[[0, 5, 10, 15, 20, 25], [1, 6, 11, 16, 21], [2, 7, 12, 17, 22], [3, 8, 13, 18, 23], [4, 9, 14, 19, 24]]
[[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]]

ध्यान दें कि सन्निहित जनरेटर अन्य दो की तरह समान लंबाई के पैटर्न में विखंडन प्रदान करते हैं, लेकिन आइटम सभी क्रम में हैं, और वे समान रूप से विभाजित हैं क्योंकि कोई असतत तत्वों की सूची को विभाजित कर सकता है।


आप कहते हैं कि उपरोक्त में से कोई भी समान रूप से आकार प्रदान नहीं करता है। लेकिन यह एक करता है, के रूप में करता है यह एक
15

1
@ प्रेंडरल, पहला वाला, list(grouper(3, xrange(7)))और दूसरा वाला, chunk(xrange(7), 3)दोनों वापस [(0, 1, 2), (3, 4, 5), (6, None, None)]:। Noneकी बस padding रहे हैं, और नहीं बल्कि मेरी राय में असजीला। वे समान रूप से पुनरावृत्तियों को नहीं देख रहे हैं। आपके वोट के लिए धन्यवाद!
हारून हॉल

4
आप प्रश्न उठाते हैं (स्पष्ट रूप से किए बिना, इसलिए मैं अब यहां करता हूं) कि क्या समान रूप से आकार के चक्र (अंतिम को छोड़कर, यदि संभव नहीं है) या क्या एक संतुलित (जितना संभव हो उतना अच्छा) परिणाम अधिक बार होता है, जिसकी आवश्यकता होगी। आप मानते हैं कि संतुलित समाधान पसंद करना है; यदि आप वास्तविक दुनिया के करीब हैं तो यह सच हो सकता है (उदाहरण के लिए एक नकली कार्ड गेम के लिए कार्ड-डीलिंग एल्गोरिदम)। अन्य मामलों में (जैसे शब्दों के साथ लाइनों को भरना) एक व्यक्ति लाइनों को यथासंभव पूर्ण रखना चाहेगा। इसलिए मैं वास्तव में एक दूसरे को पसंद नहीं कर सकता; वे सिर्फ विभिन्न उपयोग के मामलों के लिए हैं।
अल्फ

@ ChristopherBarrington-लेह अच्छा बिंदु, DataFrames के लिए, तो आप शायद स्लाइस, का उपयोग करना चाहिए के बाद से मैं DataFrame वस्तुओं आमतौर पर नहीं है जैसे टुकड़ा करने की क्रिया पर नकल का मानना हैimport pandas as pd; [pd.DataFrame(np.arange(7))[i::3] for i in xrange(3)]
हारून हॉल

1
@AaronHall उफ़। मैंने अपनी टिप्पणी हटा दी क्योंकि मैंने अपनी आलोचना का दूसरा अनुमान लगाया था, लेकिन आप ड्रॉ पर जल्दी थे। धन्यवाद! वास्तव में, मेरा दावा है कि यह डेटाफ्रेम के लिए काम नहीं करता है सच है। यदि आइटम एक डेटाफ्रेम है, तो अंतिम पंक्ति के रूप में केवल उपज आइटम (रेंज_ x_i, item_count, बास्केट) का उपयोग करें। मैंने एक अलग (अभी तक दूसरा) उत्तर दिया, जिसमें आप वांछित (न्यूनतम) समूह का आकार निर्दिष्ट करते हैं।
CPBL

38

मैंने इस प्रश्न के डुप्लिकेट में सबसे भयानक पायथन-ईश उत्तर देखा :

from itertools import zip_longest

a = range(1, 16)
i = iter(a)
r = list(zip_longest(i, i, i))
>>> print(r)
[(1, 2, 3), (4, 5, 6), (7, 8, 9), (10, 11, 12), (13, 14, 15)]

आप किसी भी n के लिए n-tuple बना सकते हैं। यदि a = range(1, 15), तो परिणाम होगा:

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

यदि सूची समान रूप से विभाजित है, तो आप के zip_longestसाथ बदल सकते हैं zip, अन्यथा ट्रिपलेट (13, 14, None)खो जाएगा। ऊपर पायथन 3 का उपयोग किया जाता है। पायथन 2 के लिए, का उपयोग करें izip_longest


यदि आपकी सूची और विखंडू कम हैं तो यह अच्छा है, आप अपनी सूची को 1000 की संख्या में विभाजित करने के लिए इसे कैसे अनुकूलित कर सकते हैं? आप "ज़िप नहीं जा रहे हैं (i, i, i, i, i, i, i, i, i, i ..... 1000)
Tom Smith

9
zip(i, i, i, ... i)ज़िप के लिए "chunk_size" तर्कों के साथ () लिखा जा सकता है कि zip(*[i]*chunk_size)क्या यह एक अच्छा विचार है या नहीं, बहस का विषय है।
विल्सन एफ

1
इसका नकारात्मक पक्ष यह है कि यदि आप समान रूप से विभाजित नहीं कर रहे हैं, तो आप तत्वों को छोड़ देंगे, क्योंकि ज़िप सबसे कम चलने योग्य पर रुक जाता है - & izip_longest डिफ़ॉल्ट तत्वों को जोड़ देगा।
हारून हॉल

zip_longestका उपयोग किया जाना चाहिए, जैसा कि इसमें किया गया है: stackoverflow.com/a/434411/1959808
Ioannis Filippidis

range(1, 15)पहले से ही गायब तत्वों के साथ जवाब है, क्योंकि 14 तत्व हैं range(1, 15), 15. नहीं
Ioannis Filippidis

35

यदि आप सूची आकार जानते हैं:

def SplitList(mylist, chunk_size):
    return [mylist[offs:offs+chunk_size] for offs in range(0, len(mylist), chunk_size)]

यदि आप (पुनरावृत्त) नहीं करते हैं:

def IterChunks(sequence, chunk_size):
    res = []
    for item in sequence:
        res.append(item)
        if len(res) >= chunk_size:
            yield res
            res = []
    if res:
        yield res  # yield the last, incomplete, portion

बाद के मामले में, इसे और अधिक सुंदर तरीके से फिर से तैयार किया जा सकता है यदि आप सुनिश्चित कर सकते हैं कि अनुक्रम में हमेशा दिए गए आकार की एक पूरी संख्या होती है (यानी कोई अंतिम अपूर्ण नहीं है)।


मुझे दुख है कि यह इतनी नीचे दफन है। IterChunks सब कुछ के लिए काम करता है और सामान्य समाधान है और मुझे पता है कि कोई चेतावनी नहीं है।
जेसन डंकेलबर्गर

18

Toolz पुस्तकालय है partitionइस के लिए समारोह:

from toolz.itertoolz.core import partition

list(partition(2, [1, 2, 3, 4]))
[(1, 2), (3, 4)]

यह सभी सुझावों में से सबसे सरल लगता है। मैं सिर्फ सोच रहा हूं कि क्या यह सच हो सकता है कि इस तरह के विभाजन समारोह को प्राप्त करने के लिए किसी तीसरे पक्ष के पुस्तकालय का उपयोग करना है। मैं भाषा विभाजन के रूप में मौजूद होने के लिए उस विभाजन फ़ंक्शन के साथ कुछ समान होने की उम्मीद कर रहा हूं।
कास्परड

1
आप itertools के साथ एक विभाजन कर सकते हैं। लेकिन मुझे टूलज़ लाइब्रेरी पसंद है। एक कार्यात्मक शैली में संग्रह पर काम करने के लिए एक क्लोजर-प्रेरित पुस्तकालय। आपको अपरिवर्तनीयता नहीं मिलती है लेकिन आपको साधारण संग्रह पर काम करने के लिए एक छोटी शब्दावली मिलती है। प्लस के रूप में, साइटोल्ज़ को साइथन में लिखा गया है और एक अच्छा प्रदर्शन को बढ़ावा मिलता है। github.com/pytoolz/cytoolz Matthewrocklin.com/blog/work/2014/05/01/Introducing-CyToolz
zach

Zach की टिप्पणी से लिंक काम करता है यदि आप अनुगामी स्लैश का उपयोग करते हैं: Matthewrocklin.com/blog/work/2014/05/01/Introducing-CyToolz
mit

17

यदि आपके पास उदाहरण के लिए 3 का आकार था, तो आप ऐसा कर सकते हैं:

zip(*[iterable[i::3] for i in range(3)]) 

स्रोत: http://code.activestate.com/recipes/303060-group-a-list-into-fterentialential-n-tuples/

मैं इसका उपयोग तब करूंगा जब मेरे चंक का आकार निश्चित संख्या मैं टाइप कर सकता है, जैसे '3', और कभी नहीं बदलेगा।


11
यह काम नहीं करता है अगर len (iterable)% 3! = 0. संख्याओं का अंतिम (छोटा) समूह वापस नहीं किया जाएगा।
शेरबंग

16

मुझे पायजोन डॉक का संस्करण पसंद है जो टज़ोट और जेएफएसबेस्टियन द्वारा प्रस्तावित है, लेकिन इसकी दो कमियाँ हैं:

  • यह बहुत स्पष्ट नहीं है
  • मैं आमतौर पर अंतिम चंक में एक भरने का मूल्य नहीं चाहता

मैं अपने कोड में इसका बहुत उपयोग कर रहा हूं:

from itertools import islice

def chunks(n, iterable):
    iterable = iter(iterable)
    while True:
        yield tuple(islice(iterable, n)) or iterable.next()

अद्यतन: एक आलसी हिस्सा संस्करण:

from itertools import chain, islice

def chunks(n, iterable):
   iterable = iter(iterable)
   while True:
       yield chain([next(iterable)], islice(iterable, n-1))

while Trueलूप के लिए ब्रेक की स्थिति क्या है ?
वेजेंड्रिया

@wjrearea: खाली StopIterationहोने पर उठाया tupleऔर iterable.next()निष्पादित हो जाता है। हालांकि, आधुनिक पायथन में ठीक से काम नहीं करता है, जहां एक जनरेटर से बाहर निकलना चाहिए return, न कि ऊपर उठाना StopIteration। एक try/except StopIteration: returnपूरे लूप (और बदलते आसपास iterable.next()के next(iterable)पार संस्करण compat के लिए) कम से कम न्यूनतम भूमि के ऊपर के साथ यह समस्या नहीं आती।
शैडो रेंजर

15
[AA[i:i+SS] for i in range(len(AA))[::SS]]

जहाँ एए सरणी है, एसएस चंक आकार है। उदाहरण के लिए:

>>> AA=range(10,21);SS=3
>>> [AA[i:i+SS] for i in range(len(AA))[::SS]]
[[10, 11, 12], [13, 14, 15], [16, 17, 18], [19, 20]]
# or [range(10, 13), range(13, 16), range(16, 19), range(19, 21)] in py3

2
यह सबसे अच्छा और सरल है।
F.Tamy

2
छोटा और सरल। जटिलता पर सादगी।
dkrynicki

15

मैं विभिन्न तरीकों के प्रदर्शन के बारे में उत्सुक था और यहाँ यह है:

पायथन 3.5.1 पर परीक्षण किया गया

import time
batch_size = 7
arr_len = 298937

#---------slice-------------

print("\r\nslice")
start = time.time()
arr = [i for i in range(0, arr_len)]
while True:
    if not arr:
        break

    tmp = arr[0:batch_size]
    arr = arr[batch_size:-1]
print(time.time() - start)

#-----------index-----------

print("\r\nindex")
arr = [i for i in range(0, arr_len)]
start = time.time()
for i in range(0, round(len(arr) / batch_size + 1)):
    tmp = arr[batch_size * i : batch_size * (i + 1)]
print(time.time() - start)

#----------batches 1------------

def batch(iterable, n=1):
    l = len(iterable)
    for ndx in range(0, l, n):
        yield iterable[ndx:min(ndx + n, l)]

print("\r\nbatches 1")
arr = [i for i in range(0, arr_len)]
start = time.time()
for x in batch(arr, batch_size):
    tmp = x
print(time.time() - start)

#----------batches 2------------

from itertools import islice, chain

def batch(iterable, size):
    sourceiter = iter(iterable)
    while True:
        batchiter = islice(sourceiter, size)
        yield chain([next(batchiter)], batchiter)


print("\r\nbatches 2")
arr = [i for i in range(0, arr_len)]
start = time.time()
for x in batch(arr, batch_size):
    tmp = x
print(time.time() - start)

#---------chunks-------------
def chunks(l, n):
    """Yield successive n-sized chunks from l."""
    for i in range(0, len(l), n):
        yield l[i:i + n]
print("\r\nchunks")
arr = [i for i in range(0, arr_len)]
start = time.time()
for x in chunks(arr, batch_size):
    tmp = x
print(time.time() - start)

#-----------grouper-----------

from itertools import zip_longest # for Python 3.x
#from six.moves import zip_longest # for both (uses the six compat library)

def grouper(iterable, n, padvalue=None):
    "grouper(3, 'abcdefg', 'x') --> ('a','b','c'), ('d','e','f'), ('g','x','x')"
    return zip_longest(*[iter(iterable)]*n, fillvalue=padvalue)

arr = [i for i in range(0, arr_len)]
print("\r\ngrouper")
start = time.time()
for x in grouper(arr, batch_size):
    tmp = x
print(time.time() - start)

परिणाम:

slice
31.18285083770752

index
0.02184295654296875

batches 1
0.03503894805908203

batches 2
0.22681021690368652

chunks
0.019841909408569336

grouper
0.006506919860839844

3
timeपुस्तकालय का उपयोग करते हुए बेंचमार्किंग करना एक बहुत अच्छा विचार नहीं है जब हमारे पास timeitमॉड्यूल है
अज़ात इब्राकोव

13

कोड:

def split_list(the_list, chunk_size):
    result_list = []
    while the_list:
        result_list.append(the_list[:chunk_size])
        the_list = the_list[chunk_size:]
    return result_list

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

print split_list(a_list, 3)

परिणाम:

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

12

आप पुस्तकालय के get_chunksकार्य का भी उपयोग कर सकते हैं utilspie:

>>> from utilspie import iterutils
>>> a = [1, 2, 3, 4, 5, 6, 7, 8, 9]

>>> list(iterutils.get_chunks(a, 5))
[[1, 2, 3, 4, 5], [6, 7, 8, 9]]

आप utilspieपाइप के माध्यम से स्थापित कर सकते हैं :

sudo pip install utilspie

डिस्क्लेमर: मैं यूटिलिटी लाइब्रेरी का निर्माता हूं


11

इस बिंदु पर, मुझे लगता है कि हमें केवल मामले में एक पुनरावर्ती जनरेटर की आवश्यकता है ...

अजगर 2 में:

def chunks(li, n):
    if li == []:
        return
    yield li[:n]
    for e in chunks(li[n:], n):
        yield e

अजगर 3 में:

def chunks(li, n):
    if li == []:
        return
    yield li[:n]
    yield from chunks(li[n:], n)

इसके अलावा, बड़े पैमाने पर विदेशी आक्रमण के मामले में, एक सजाया हुआ पुनरावर्ती जनरेटर उपयोगी हो सकता है:

def dec(gen):
    def new_gen(li, n):
        for e in gen(li, n):
            if e == []:
                return
            yield e
    return new_gen

@dec
def chunks(li, n):
    yield li[:n]
    for e in chunks(li[n:], n):
        yield e

9

पायथन 3.8 में असाइनमेंट एक्सप्रेशंस के साथ यह काफी अच्छा हो जाता है:

import itertools

def batch(iterable, size):
    it = iter(iterable)
    while item := list(itertools.islice(it, size)):
        yield item

यह एक मनमाना चलने पर काम करता है, न कि केवल एक सूची पर।

>>> import pprint
>>> pprint.pprint(list(batch(range(75), 10)))
[[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]]

1
अब यह इस सवाल का एक नया जवाब है। मुझे वास्तव में यह काफी पसंद है। मुझे असाइनमेंट एक्सप्रेशंस पर संदेह है, लेकिन जब वे काम करते हैं तो काम करते हैं।
juanpa.arrivillaga

7

हे, एक पंक्ति संस्करण

In [48]: chunk = lambda ulist, step:  map(lambda i: ulist[i:i+step],  xrange(0, len(ulist), step))

In [49]: chunk(range(1,100), 10)
Out[49]: 
[[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, 97, 98, 99]]

36
कृपया, "chunk = lambda" के बजाय "def chunk" का उपयोग करें। यह वही काम करता है। एक पंक्ति। वही सुविधाएँ। MUCH पढ़ने और समझने के लिए n00bz के लिए आसान है।
S.Lott

4
@ S.Lott: n00bz स्कीम से आने पर नहीं: P यह कोई वास्तविक समस्या नहीं है। Google के लिए एक कीवर्ड भी है! n00bz की खातिर हम किन अन्य विशेषताओं को दिखाते हैं? मुझे लगता है कि उपज n00b के अनुकूल होने के लिए पर्याप्त नहीं है।
Janus Troelsen

16
समारोह वस्तु से उत्पन्न def chunkबजाय chunk=lambda.__ name__ विशेषता 'हिस्सा' के बजाय '<लैम्ब्डा>' है। ट्रेसबैक में विशिष्ट नाम अधिक उपयोगी है।
टेरी जान ने कॉमेडी

1
@ शेल्फ: मुझे यकीन नहीं है कि अगर इसे एक मुख्य शब्दार्थक अंतर कहा जा सकता है, लेकिन क्या ट्रेसबैक में एक उपयोगी नाम है <lamba>या नहीं, कम से कम, एक उल्लेखनीय अंतर है।
मार्टीन्यू

1
प्रदर्शन के लिए उनमें से एक गुच्छा का परीक्षण करने के बाद, यह बहुत अच्छा है!
सनी पटेल

7
def split_seq(seq, num_pieces):
    start = 0
    for i in xrange(num_pieces):
        stop = start + len(seq[i::num_pieces])
        yield seq[start:stop]
        start = stop

उपयोग:

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

for seq in split_seq(seq, 3):
    print seq

7

एक और अधिक स्पष्ट संस्करण।

def chunkList(initialList, chunkSize):
    """
    This function chunks a list into sub lists 
    that have a length equals to chunkSize.

    Example:
    lst = [3, 4, 9, 7, 1, 1, 2, 3]
    print(chunkList(lst, 3)) 
    returns
    [[3, 4, 9], [7, 1, 1], [2, 3]]
    """
    finalList = []
    for i in range(0, len(initialList), chunkSize):
        finalList.append(initialList[i:i+chunkSize])
    return finalList

(२०१६ सितंबर १२) यह उत्तर सबसे अधिक भाषा स्वतंत्र और पढ़ने में आसान है।
डी एडम्स

7

बिना कॉल किए लेन () जो बड़ी सूचियों के लिए अच्छा है:

def splitter(l, n):
    i = 0
    chunk = l[:n]
    while chunk:
        yield chunk
        i += n
        chunk = l[i:i+n]

और यह पुनरावृत्तियों के लिए है:

def isplitter(l, n):
    l = iter(l)
    chunk = list(islice(l, n))
    while chunk:
        yield chunk
        chunk = list(islice(l, n))

ऊपर का कार्यात्मक स्वाद:

def isplitter2(l, n):
    return takewhile(bool,
                     (tuple(islice(start, n))
                            for start in repeat(iter(l))))

या:

def chunks_gen_sentinel(n, seq):
    continuous_slices = imap(islice, repeat(iter(seq)), repeat(0), repeat(n))
    return iter(imap(tuple, continuous_slices).next,())

या:

def chunks_gen_filter(n, seq):
    continuous_slices = imap(islice, repeat(iter(seq)), repeat(0), repeat(n))
    return takewhile(bool,imap(tuple, continuous_slices))

16
len()बड़ी सूची से बचने का कोई कारण नहीं है ; यह एक निरंतर समय संचालन है।
थॉमस वाउटर्स

7

यहाँ अतिरिक्त दृष्टिकोणों की एक सूची दी गई है:

दिया हुआ

import itertools as it
import collections as ct

import more_itertools as mit


iterable = range(11)
n = 3

कोड

मानक पुस्तकालय

list(it.zip_longest(*[iter(iterable)] * n))
# [(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, None)]

d = {}
for i, x in enumerate(iterable):
    d.setdefault(i//n, []).append(x)

list(d.values())
# [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10]]

dd = ct.defaultdict(list)
for i, x in enumerate(iterable):
    dd[i//n].append(x)

list(dd.values())
# [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10]]

more_itertools+

list(mit.chunked(iterable, n))
# [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10]]

list(mit.sliced(iterable, n))
# [range(0, 3), range(3, 6), range(6, 9), range(9, 11)]

list(mit.grouper(n, iterable))
# [(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, None)]

list(mit.windowed(iterable, len(iterable)//n, step=n))
# [(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, None)]

संदर्भ

+ एक तृतीय-पक्ष पुस्तकालय जो इटर्लस व्यंजनों और अधिक को लागू करता है> pip install more_itertools


6

इस संदर्भ को देखें

>>> orange = range(1, 1001)
>>> otuples = list( zip(*[iter(orange)]*10))
>>> print(otuples)
[(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), ... (991, 992, 993, 994, 995, 996, 997, 998, 999, 1000)]
>>> olist = [list(i) for i in otuples]
>>> print(olist)
[[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], ..., [991, 992, 993, 994, 995, 996, 997, 998, 999, 1000]]
>>> 

python3


3
अच्छा है, लेकिन अंत में तत्वों को छोड़ देता है यदि आकार पूरी संख्या में विखंडू से मेल नहीं खाता है, उदाहरण के लिए zip(*[iter(range(7))]*3)केवल रिटर्न [(0, 1, 2), (3, 4, 5)]और 6इनपुट से भूल जाता है ।
अल्फ

6

चूंकि यहां हर कोई पुनरावृत्तियों के बारे में बात कर रहा है। boltonsकहा जाता है कि के लिए एकदम सही विधि है iterutils.chunked_iter

from boltons import iterutils

list(iterutils.chunked_iter(list(range(50)), 11))

आउटपुट:

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

लेकिन अगर आप स्मृति पर दया नहीं करना चाहते हैं, तो आप पुराने तरीके का उपयोग कर सकते हैं और listपहले वाले स्थान पर पूर्ण स्टोर कर सकते हैं iterutils.chunked


और यह वास्तव में आदेश की परवाह किए बिना काम करता है एक सबअटरेटर देखता है !!
पीटर गेर्ड्स

6

एक और उपाय

def make_chunks(data, chunk_size): 
    while data:
        chunk, data = data[:chunk_size], data[chunk_size:]
        yield chunk

>>> for chunk in make_chunks([1, 2, 3, 4, 5, 6, 7], 2):
...     print chunk
... 
[1, 2]
[3, 4]
[5, 6]
[7]
>>> 

5
def chunks(iterable,n):
    """assumes n is an integer>0
    """
    iterable=iter(iterable)
    while True:
        result=[]
        for i in range(n):
            try:
                a=next(iterable)
            except StopIteration:
                break
            else:
                result.append(a)
        if result:
            yield result
        else:
            break

g1=(i*i for i in range(10))
g2=chunks(g1,3)
print g2
'<generator object chunks at 0x0337B9B8>'
print list(g2)
'[[0, 1, 4], [9, 16, 25], [36, 49, 64], [81]]'

1
हालांकि यह बहुत कम या उतने सुंदर नहीं लग सकते हैं, जितने कि इटर्लस आधारित प्रतिक्रियाएँ हैं, यह वास्तव में काम करता है यदि आप पहली बार पहुँचने से पहले दूसरी उप-सूची का प्रिंट आउट लेना चाहते हैं, तो आप i0 = अगला (g2) सेट कर सकते हैं; i1 = (G2) अगले; और i1 का उपयोग करने से पहले i1 का उपयोग करें और यह टूटता नहीं है !!
पीटर गेर्ड्स

5

Matplotlib.cbook टुकड़ों का उपयोग करने पर विचार करें

उदाहरण के लिए:

import matplotlib.cbook as cbook
segments = cbook.pieces(np.arange(20), 3)
for s in segments:
     print s

लगता है कि आपने गलती से दो खाते बनाए हैं। आप उन्हें मर्ज करने के लिए टीम से संपर्क कर सकते हैं , जो आपको अपने योगदान पर सीधे संपादन विशेषाधिकार प्राप्त करने की अनुमति देगा।
जॉर्जी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.