আপনি কীভাবে সমান আকারের অংশগুলিতে একটি তালিকা বিভক্ত করবেন?


2263

আমার নির্বিচার দৈর্ঘ্যের একটি তালিকা রয়েছে এবং আমার এটি সমান আকারের অংশে বিভক্ত করা এবং এটি চালনা করা দরকার। এটি করার কয়েকটি সুস্পষ্ট উপায় রয়েছে, যেমন একটি কাউন্টার এবং দুটি তালিকাগুলি রাখা, এবং দ্বিতীয় তালিকাটি পূরণ করার পরে, এটি প্রথম তালিকায় যুক্ত করুন এবং পরবর্তী তালিকার দ্বিতীয় পর্বের জন্য দ্বিতীয় তালিকাটি খালি করুন, তবে এটি সম্ভাব্যভাবে ব্যয়বহুল।

আমি ভাবছিলাম যে কোনও দৈর্ঘ্যের তালিকার জন্য যেমন কারও কাছে এর ভাল সমাধান আছে, যেমন জেনারেটর ব্যবহার করে।

আমি দরকারী কিছু খুঁজছিলাম itertoolsকিন্তু আমি স্পষ্টত দরকারী কিছু খুঁজে পেল না। যদিও এটি মিস হয়ে গেছে।

সম্পর্কিত প্রশ্ন: খণ্ডে একটি তালিকা পুনরাবৃত্তি সবচেয়ে "পাইথোনিক" উপায় কি?


1
আপনি একটি নতুন উত্তর পোস্ট করার আগে, এই প্রশ্নের ইতিমধ্যে 60+ উত্তর আছে তা বিবেচনা করুন। দয়া করে নিশ্চিত হন যে আপনার উত্তরটি এমন তথ্যের অবদান রাখে যা বিদ্যমান উত্তরের মধ্যে নেই।
জান্নিক

যে ব্যবহারকারীরা নির্বিচারে ছোট চূড়ান্ত অংশ এড়াতে চান তাদের জন্য প্রায় সমান দৈর্ঘ্যের N অংশে একটি তালিকা বিভক্ত করা দেখুন
উইম

উত্তর:


3144

এখানে এমন একটি জেনারেটর রয়েছে যা আপনি চান খণ্ড ফলন:

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]

এছাড়াও আপনি কোনও ফাংশন লেখার পরিবর্তে কেবল তালিকা বোধগম্যতা ব্যবহার করতে পারেন, যদিও নামকৃত ক্রিয়াকলাপগুলিতে এই জাতীয় ক্রিয়াকলাপকে encapsulate করা ভাল ধারণা যাতে আপনার কোডটি বোঝা সহজ। পাইথন 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
এটি প্রশ্নের একটি আকর্ষণীয় এক্সটেনশন, তবে মূল প্রশ্নটি কোনও তালিকায় অপারেটিং সম্পর্কে স্পষ্টভাবে জিজ্ঞাসা করেছিল।
নেড ব্যাচেল্ডার

32
এই ফাংশন চাহিদা অভিশাপ মান লাইব্রেরিতে হতে
dgan

6
@ ক্যালিমো: আপনার কী পরামর্শ? আমি আপনাকে 47 উপাদান দিয়ে একটি তালিকা হস্তান্তর। আপনি কীভাবে এটিকে "সমান আকারের অংশগুলিতে" ভাগ করতে চান? ওপি উত্তরটি গ্রহণ করেছে, তাই তারা শেষের আকারের শেষ আকারের সাথে পরিষ্কারভাবে ঠিক আছে। সম্ভবত ইংরেজী বাক্যাংশটি অনর্থক?
নেড ব্যাচেল্ডার

7
দয়া করে আপনার ভেরিয়েবলের নাম রাখবেন না, এটি দেখতে ঠিক 1 টির মতো এবং বিভ্রান্তিকর। লোকেরা আপনার কোডটি অনুলিপি করছে এবং মনে করে এটি ঠিক আছে।
ইয়াসেন

555

আপনি যদি খুব সাধারণ কিছু চান:

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

পাইথন ২.x এর xrange()পরিবর্তে ব্যবহার করুনrange()


6
অথবা (যদি আমরা এই নির্দিষ্ট ফাংশনের বিভিন্ন উপস্থাপনা করছি) আপনি ল্যাম্বডা ফাংশনটি সংজ্ঞায়িত করতে পারেন: ল্যাম্বদা এক্স, ওয়াই: [এক্স [i: i + y] আই রেঞ্জের জন্য (0, লেন (এক্স), y) ]। আমি এই তালিকা উপলব্ধি পদ্ধতি পছন্দ!
জেপি

4
প্রত্যাবর্তনের পরে অবশ্যই অবশ্যই [, নয় (
alwbtc

2
"সুপার সিম্পল" অর্থ অনন্ত লুপগুলি ডিবাগ করা না - এর জন্য কুডো max()
বব স্টেইন

এই সমাধানটি সম্পর্কে সহজ কিছুই নেই
মিট করুন

1
@ নাহোজ_গনক ওফস এটি কোনও অসীম লুপ নয়, তবে খণ্ডগুলি (এল, 0) সর্বোচ্চ () ছাড়াই একটি মান বাড়িয়ে তুলবে। পরিবর্তে, সর্বোচ্চ () 1 এর চেয়ে কম কিছুকে 1 তে পরিণত করে
বব স্টেইন

294

সরাসরি (পুরাতন) পাইথন ডকুমেন্টেশন (এটির টোলগুলির রেসিপি) থেকে:

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)

জেএফএসবেস্টিয়ানের পরামর্শ অনুসারে বর্তমান সংস্করণ:

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

আমার ধারণা গিডোর টাইম মেশিন আবার কাজ করছে — কাজ করেছে work কাজ করবে worked কাজ করবে —

এই সমাধানগুলি কাজ করে কারণ [iter(iterable)]*n(বা পূর্ববর্তী সংস্করণটির সমতুল্য) তালিকায় বারবার একটি পুনরাবৃত্তি তৈরি করে nizip_longestতারপরে কার্যকরভাবে "প্রতিটি" পুনরাবৃত্তির একটি রাউন্ড-রবিন সম্পাদন করে; কারণ এটি একই পুনরুক্তিকারী, এটি প্রতিটি কল দ্বারা এটি উন্নত, এর ফলে প্রতিটি জিপ-রাউন্ড্রোবিন nআইটেমগুলির একটি টুপল উত্পন্ন করে ।


@ নিনজাগেকো: list(grouper(3, range(10)))রিটার্ন [(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, None, None)], এবং সমস্ত টিপলস দৈর্ঘ্যের 3 Please আপনার মন্তব্যটি বিস্তারিতভাবে বর্ণনা করুন কারণ আমি এটি বুঝতে পারি না; আপনি কোন জিনিসকে কী বলে এবং কীভাবে আপনি এটি " 3 এর গুণক হওয়ার প্রত্যাশায়" 3 এর একাধিক বলে সংজ্ঞা দেন ? তুমাকে অগ্রিম ধন্যবাদ.
tzot

14
এটি উত্সাহিত করা হয়েছে কারণ এটি জেনারেটরে (কোনও লেন নেই) কাজ করে এবং সাধারণত দ্রুততর ইটারটুল মডিউলটি ব্যবহার করে।
মাইকেল ডিলন

88
itertoolsসাধারণ এবং নিষ্পাপ খাঁটি অজগর বাস্তবায়নের তুলনায় যখন অভিনব ফাংশনাল পদ্ধতির কিছু অপঠনযোগ্য কাঁচকে ঘুরিয়ে দেওয়ার সর্বোত্তম উদাহরণ
উইম

15
@ উইম প্রদত্ত যে এই উত্তরটি পাইথন ডকুমেন্টেশন থেকে একটি স্নিপেট হিসাবে শুরু হয়েছিল, আমি আপনাকে বাগস.পিথন.আর.আরজে একটি সমস্যা খোলার পরামর্শ দিই
tzot

1
@pedrosaurio যদি l==[1, 2, 3]তারপর f(*l)সমতূল্য f(1, 2, 3)। দেখুন যে প্রশ্ন এবং সরকারী ডকুমেন্টেশন
tzot

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 টি উপাদান বা পাঁচটি 2 টি উপাদানগুলিতে ভাগ করতে পারেন
Moj

24
+1 এটি আমার প্রিয় সমাধান, কারণ এটি অ্যারেটিকে সমান আকারের অ্যারেগুলিতে বিভক্ত করে , অন্য সমাধানগুলি না করে (অন্য সমস্ত সমাধানে আমি দেখেছি, শেষ অ্যারেটি নির্বিচারে ছোট হতে পারে)।
MiniQuark

@ মিনিকিয়ার্ক তবে ব্লক সংখ্যাটি মূল অ্যারের আকারের ফ্যাক্টর না হলে এটি কী করবে?
বাল্ড্রিক

1
@ বালড্রিক আপনি যদি এন উপাদানগুলিকে কে অংশগুলিতে বিভক্ত করেন তবে প্রথম এন% কে অংশগুলিতে এন // কে + 1 উপাদান থাকবে এবং বাকী অংশগুলিতে এন // কে উপাদান থাকবে। উদাহরণস্বরূপ, আপনি যদি 108 টি উপাদান যুক্ত অ্যারেটিকে 5 টি অংশে বিভক্ত করেন তবে প্রথম 108% 5 = 3 অংশগুলিতে 108 // 5 + 1 = 22 উপাদান থাকবে এবং বাকী অংশগুলিতে 108/5 = 21 থাকবে উপাদান।
MiniQuark 15

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ভিত্তিক সমাধানগুলির মতো , উপরের সর্বদা প্যাডগুলি। যতদুর আমি জানি, সেখানে একটি ফাংশন যে জন্য কোন এক- বা দুই-লাইন itertools রেসিপি ঐচ্ছিকরূপে প্যাড। উপরোক্ত দুটি পদ্ধতির সংমিশ্রণের মাধ্যমে, এটি একটি খুব কাছাকাছি আসে:

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

আমি বিশ্বাস করি এটি প্রস্তাবিত সবচেয়ে সংক্ষিপ্ততম চুনকার যা alচ্ছিক প্যাডিং সরবরাহ করে।

টমসজ গ্যান্ডোর যেমন পর্যবেক্ষণ করেছেন , প্যাড মানগুলির দীর্ঘ ক্রমিকের মুখোমুখি হলে দুটি প্যাডিং চঙ্কারগুলি অপ্রত্যাশিতভাবে থামবে। এখানে একটি চূড়ান্ত প্রকরণ যা এই সমস্যাটির চারপাশে যুক্তিসঙ্গত উপায়ে কাজ করে:

_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
এই কারণেই আমি কেবল শীর্ষ দম্পতিকে স্ক্যান করার চেয়ে উত্তরগুলি দিয়ে পড়েছিলাম। Caseচ্ছিক প্যাডিং আমার ক্ষেত্রে প্রয়োজন ছিল এবং আমিও ইটারের দ্বি-যুক্তির ফর্মটি শিখেছি।
কের

আমি এটিকে উন্নত করে দিয়েছি, তবুও - আসুন এটির ওভারহাইপ না করি! প্রথম সব, ল্যামডা উপর খারাপ (ধীর অবসান হতে পারে itপুনরুক্তিকারীর দ্বিতীয়ত, এবং সবচেয়ে importanlty -। আপনি অকালে শেষ হয়ে যাবে একটি খণ্ড যদি padvalআসলে আপনার iterable বিদ্যমান, এবং প্রক্রিয়া দিতে হবে।
Tomasz Gandor

@ টমাসজেন্ডার, আমি আপনার প্রথম পয়েন্টটি নিয়েছি! যদিও আমার বোধগম্যতা হল যে ল্যাম্বদা কোনও সাধারণ ক্রিয়াকলাপের চেয়ে ধীর নয়, অবশ্যই আপনি ঠিক বলেছেন যে ফাংশন কল এবং ক্লোজার চেহারাটি এটি ধীর করবে। আমি জানি না izip_longestযে এটির তুলনামূলক পারফরম্যান্স হিটটি কীভাবে বনামের দিকে চলবে , উদাহরণস্বরূপ - আমি সন্দেহ করি এটি একটি জটিল বাণিজ্য-বন্ধ হতে পারে। তবে ... padvalএখানে প্রতি উত্তরের দ্বারা ভাগ করা সমস্যাটি নেই যা padvalপরামিতি সরবরাহ করে?
প্রেরক

1
@ টমাসজান্ডার, যথেষ্ট ফর্সা! তবে এটির সমাধান করে এমন কোনও সংস্করণ তৈরি করা খুব কঠিন ছিল না। (এছাড়াও, মনে রাখবেন প্রথম সংস্করণে দেখানো হয় ব্যবহার করে ()প্রহরী হিসেবে কাজ করে কাজ সঠিকভাবে কারণ নেই। tuple(islice(it, size))উৎপাদনের ()যখন itখালি।)
senderle

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
@ টমাসজওয়াইস্কি আপনি কি পুনরাবৃত্তকারীকে আপনার *সামনে ব্যাখ্যা করতে পারবেন ? সম্ভবত আপনার উত্তর পাঠ্যে, তবে আমি লক্ষ্য করেছি *যে পাইথনে আগে সেভাবে ব্যবহৃত হয়েছিল। ধন্যবাদ!
দ্য জলিসিন

1
এই প্রসঙ্গে, এটি স্প্লিট অপারেটর বলা হয় operator এর ব্যবহারটি এখানে ব্যাখ্যা করা হয়েছে - stackoverflow.com/questions/5917522/unziping- এবং- the - operator
rlms

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
লাম্বডাস অর্থ নামহীন ফাংশন হিসাবে ব্যবহার করা হয়। তাদের সেভাবে ব্যবহার করার কোনও মানে নেই। এছাড়াও এটি ডিবাগিংকে আরও কঠিন করে তোলে কারণ ট্রেসব্যাক ত্রুটির ক্ষেত্রে "অংশগুলিতে" পরিবর্তে "<lambda>" তে রিপোর্ট করবে। আমি আশা করি আপনার ভাগ্য এই সমস্যাগুলির পুরো গুচ্ছ থাকলে :)
ক্রিস কোস্টন

1
এটি এক্সরেঞ্জ ইন 0 এর মধ্যে 0 নয় 1 হওয়া উচিতprint [l[x:x+10] for x in xrange(1, len(l), 10)]
স্কটিডেল্টা

দ্রষ্টব্য: পাইথন 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এর মাত্র প্যাডিং প্রয়োগ করা হয়, এবং বরং আমার মতে অসুন্দর। তারা সমানভাবে পুনরাবৃত্তিকে ছাঁটাই করছে না।

কেন আমরা এগুলি আরও ভাল ভাগ করতে পারি না?

আমার সমাধান (গুলি)

এখানে একটি সুষম সমাধান, একটি ফাংশন থেকে অভিযোজিত আমি উৎপাদনে ব্যবহার করেছি (পাইথন 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]]

লক্ষ্য করুন যে সংক্ষিপ্ত জেনারেটর অন্যান্য দুটি হিসাবে একই দৈর্ঘ্যের ধরণগুলিতে খণ্ড সরবরাহ করে তবে আইটেমগুলি সমস্ত ক্রমযুক্ত এবং এগুলি সমানভাবে বিভক্ত হয় যেমন একটি পৃথক উপাদানগুলির তালিকায় বিভক্ত হতে পারে।


আপনি বলছেন যে উপরের কোনওটি সমান আকারের খণ্ড সরবরাহ করে না। কিন্তু এই এক করে, যেমন করে এই এক
প্রেরক

1
@senderle, প্রথম এক, list(grouper(3, xrange(7)))এবং দ্বিতীয় এক, chunk(xrange(7), 3)উভয় রিটার্ন: [(0, 1, 2), (3, 4, 5), (6, None, None)]Noneএর মাত্র প্যাডিং প্রয়োগ করা হয়, এবং বরং আমার মতে অসুন্দর। তারা সমানভাবে পুনরাবৃত্তিকে ছাঁটাই করছে না। আপনার ভোটের জন্য ধন্যবাদ!
অ্যারন হল

4
আপনি প্রশ্ন উত্থাপন করুন (এটি স্পষ্টভাবে না করেই, তাই আমি এখন এখানে এটি করি) সমান আকারের খণ্ডগুলি (শেষ ব্যতীত, যদি সম্ভব না হয় তবে) বা ভারসাম্যযুক্ত (যতটা সম্ভব ভাল) ফলাফলটি প্রায়শই প্রয়োজন হয় যা প্রয়োজন। আপনি ধরে নিলেন যে সুষম সমাধানটি পছন্দ করা; আপনার প্রোগ্রামটি যা সত্যিকারের বিশ্বের (যেমন একটি সিমুলেটেড কার্ড গেমের জন্য কার্ড-ডিলিং অ্যালগরিদম) এর কাছাকাছি থাকলে এটি সত্য হতে পারে। অন্যান্য ক্ষেত্রে (শব্দের সাথে রেখাগুলি পূরণের মতো) লাইনগুলি যতটা সম্ভব পূর্ণ করে রাখা পছন্দ করবে। সুতরাং আমি সত্যিই একে অপরের চেয়ে বেশি পছন্দ করতে পারি না; এগুলি কেবল বিভিন্ন ব্যবহারের ক্ষেত্রে।
আলফ

@ ক্রিস্টোফারবারিংটন-লে গুড পয়েন্ট, ডাটাফ্রেমের জন্য আপনার সম্ভবত টুকরা ব্যবহার করা উচিত, যেহেতু আমি বিশ্বাস করি যে ডেটাফ্রেম অবজেক্টগুলি সাধারণত কাটানোর ক্ষেত্রে অনুলিপি করে না, যেমনimport pandas as pd; [pd.DataFrame(np.arange(7))[i::3] for i in xrange(3)]
অ্যারন হল

1
অ্যারোনহাল ওফস আমি আমার মন্তব্যটি মুছে ফেলেছি কারণ আমি আমার সমালোচনা দ্বিতীয়-অনুমান করেছি, তবে আপনি ড্রতে দ্রুত ছিলেন। ধন্যবাদ! আসলে, আমার দাবি যে এটি ডেটাফ্রেমে কাজ করে না সত্য। আইটেমগুলি যদি ডেটাফ্রেম হয় তবে কেবল ফলন আইটেমগুলি [রেঞ্জ (x_i, আইটেম_কাউন্ট, ঝুড়ি)] শেষ লাইন হিসাবে ব্যবহার করুন। আমি একটি পৃথক (আরও একটি) উত্তর অফার করেছি, যাতে আপনি পছন্দসই (ন্যূনতম) গ্রুপ আকার নির্দিষ্ট করেন specify
সিপিবিএল

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

আপনি যে কোনও এন এর জন্য এন-টিপল তৈরি করতে পারেন। যদি 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 এর অংশগুলিতে বিভক্ত করতে আপনি কীভাবে এইটিকে মানিয়ে নিতে পারেন? আপনি "কোড জিপ যাচ্ছেন না (আমি, আমি, আমি, আমি, আমি, আমি, আমি, আমি, আমি ..... আমি = 1000)
টম স্মিথ

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)ইতিমধ্যে নিখোঁজ উপাদানগুলির মধ্যে রয়েছে, কারণ range(1, 15)15
টিতে

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

পরবর্তী ক্ষেত্রে, এটি আরও সুন্দর উপায়ে পুনঃব্যবস্থা করা যেতে পারে যদি আপনি নিশ্চিত হন যে ক্রমটি সর্বদা প্রদত্ত আকারের পুরো সংখ্যাটি থাকে (যেমন শেষের কোনও অসম্পূর্ণ অংশ নেই)।


আমি দু: খিত এটি এতদূর নিচে সমাধিস্থ হয়। IterCunks সব কিছুর জন্য কাজ করে এবং এটি সাধারণ সমাধান এবং আমি জানি এমন কোনও সতর্কতা নেই।
জেসন ডানকেলবার্গার

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 এর মন্তব্য থেকে লিঙ্ক কাজ করে যদি আপনি চিহ্ন স্ল্যাশ ommit: 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/recips/303060-group-a-list-into-sequential-n-tuples/

আমার খণ্ডের আকারটি আমি টাইপ করতে পারে এমন স্থির সংখ্যাটি নির্দিষ্ট করে রাখি, যেমন '3', এবং কখনই পরিবর্তন হবে না।


11
লেন (পুনরাবৃত্ত)% 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?
wjandrea

@ ওজান্দ্রিয়া: 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
এটি সেরা এবং সহজ।
এফ.ট্যামি

2
সংক্ষিপ্ত এবং সহজ জটিলতার উপর সরলতা।
dkrynicki

15

আমি বিভিন্ন পদ্ধতির অভিনয় সম্পর্কে কৌতূহল ছিলাম এবং এটি এখানে:

পাইথন ২.০.১. তে পরীক্ষা করা হয়েছে

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

পাইথন ৩.৮ এ অ্যাসাইনমেন্ট এক্সপ্রেশন দিয়ে এটি বেশ সুন্দর হয়ে ওঠে:

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
দয়া করে, "ছান = ল্যাম্বদা" এর পরিবর্তে "ডিফ চঙ্ক" ব্যবহার করুন। এটি একই কাজ করে। এক লাইন. একই বৈশিষ্ট্য। পড়তে ও বুঝতে n00bz এর পক্ষে অনেক সহজ।
এস .লট

4
@ এস.লট: এন 100 বিজেড যদি স্কিম থেকে আসে না: পি এটি আসল সমস্যা নয়। গুগলে কীওয়ার্ডও আছে! অন্যান্য বৈশিষ্ট্যগুলি কী দেখায় যে আমরা n00bz এর খাতিরে এড়াতে পারি? আমি অনুমান করি যে ফলন অতীব প্রয়োজনীয় / সি-এর মতো নয় তবে এন00 বি বন্ধুত্বপূর্ণ হবে।
জানুস ট্রয়লসন

16
এর def chunkপরিবর্তে ফাংশনটির অবজেক্টটিতে chunk=lambda________ << লাম্বদা> এর পরিবর্তে 'অংশ' বৈশিষ্ট্য রয়েছে। নির্দিষ্ট নামটি ট্রেসব্যাকগুলিতে আরও কার্যকর more
টেরি জান রিডি

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

(2016 সেপ্টেম্বর 12) এই উত্তরটি সর্বাধিক ভাষা স্বতন্ত্র এবং পড়ার পক্ষে সহজ।
ডি অ্যাডামস

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 = পরের (জি 2) সেট করতে পারেন, তবে এটির মতো অনেকগুলি ইয়ারটোল ভিত্তিক প্রতিক্রিয়া যতটা সংক্ষিপ্ত বা সুন্দর দেখাবে না; i1 = (G2) পরবর্তী; এবং i0 ব্যবহারের আগে i1 ব্যবহার করুন এবং এটি ভাঙবে না !!
পিটার গার্ডেস

5

Matplotlib.cbook টুকরা ব্যবহার বিবেচনা করুন

উদাহরণ স্বরূপ:

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

দেখে মনে হচ্ছে আপনি দুর্ঘটনাক্রমে দুটি অ্যাকাউন্ট তৈরি করেছেন। আপনি তাদের একীভূত করতে টিমের সাথে যোগাযোগ করতে পারেন, যা আপনাকে আপনার অবদানের উপর সরাসরি সম্পাদনার সুযোগগুলি ফিরে পেতে দেয়।
জর্জি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.