ما هو أكثر "pythonic" الطريق إلى تكرار أكثر من قائمة في قطع?

StackOverflow https://stackoverflow.com/questions/434287

سؤال

لدي بيثون السيناريو الذي يأخذ كمدخل قائمة من الأعداد الصحيحة ، التي أنا بحاجة إلى العمل مع أربعة الأعداد الصحيحة في كل مرة.للأسف أنا لا أملك السيطرة على المدخلات ، أو كنت قد مرت في قائمة من أربعة عناصر الصفوف.حاليا أنا بالتكرار على هذا النحو:

for i in xrange(0, len(ints), 4):
    # dummy op for example code
    foo += ints[i] * ints[i + 1] + ints[i + 2] * ints[i + 3]

يبدو الكثير مثل "ج-التفكير" ، على الرغم مما يجعلني أشك في أن يكون هناك أكثر pythonic طريقة للتعامل مع هذا الوضع.قائمة يتم التخلص منها بعد بالتكرار ، لذلك فإنه لا يلزم أن يكون الحفاظ عليها.ربما شيء مثل هذا من شأنه أن يكون أفضل ؟

while ints:
    foo += ints[0] * ints[1] + ints[2] * ints[3]
    ints[0:4] = []

لا تزال لا "يشعر" صحيح.:-/

ذات السؤال: كيف يمكنك تقسيم القائمة إلى بالتساوي الحجم قطع في الثعبان ؟

هل كانت مفيدة؟

المحلول

تعديل من وصفات قسم بايثون itertools مستندات:

from itertools import zip_longest

def grouper(iterable, n, fillvalue=None):
    args = [iter(iterable)] * n
    return zip_longest(*args, fillvalue=fillvalue)

على سبيل المثال
في شبة الكود للحفاظ على سبيل المثال مقتضب.

grouper('ABCDEFG', 3, 'x') --> 'ABC' 'DEF' 'Gxx'

ملاحظة: في بيثون 2 استخدام izip_longest بدلا من zip_longest.

نصائح أخرى

def chunker(seq, size):
    return (seq[pos:pos + size] for pos in range(0, len(seq), size))
# (in python 2 use xrange() instead of range() to avoid allocating a list)

وبسيط. سهل. بسرعة. يعمل مع أي تسلسل:

text = "I am a very, very helpful text"

for group in chunker(text, 7):
   print repr(group),
# 'I am a ' 'very, v' 'ery hel' 'pful te' 'xt'

print '|'.join(chunker(text, 10))
# I am a ver|y, very he|lpful text

animals = ['cat', 'dog', 'rabbit', 'duck', 'bird', 'cow', 'gnu', 'fish']

for group in chunker(animals, 3):
    print group
# ['cat', 'dog', 'rabbit']
# ['duck', 'bird', 'cow']
# ['gnu', 'fish']

وأنا من محبي

chunk_size= 4
for i in range(0, len(ints), chunk_size):
    chunk = ints[i:i+chunk_size]
    # process chunk of size <= chunk_size
import itertools
def chunks(iterable,size):
    it = iter(iterable)
    chunk = tuple(itertools.islice(it,size))
    while chunk:
        yield chunk
        chunk = tuple(itertools.islice(it,size))

# though this will throw ValueError if the length of ints
# isn't a multiple of four:
for x1,x2,x3,x4 in chunks(ints,4):
    foo += x1 + x2 + x3 + x4

for chunk in chunks(ints,4):
    foo += sum(chunk)

وهناك طريقة أخرى:

import itertools
def chunks2(iterable,size,filler=None):
    it = itertools.chain(iterable,itertools.repeat(filler,size-1))
    chunk = tuple(itertools.islice(it,size))
    while len(chunk) == size:
        yield chunk
        chunk = tuple(itertools.islice(it,size))

# x2, x3 and x4 could get the value 0 if the length is not
# a multiple of 4.
for x1,x2,x3,x4 in chunks2(ints,4,0):
    foo += x1 + x2 + x3 + x4
from itertools import izip_longest

def chunker(iterable, chunksize, filler):
    return izip_longest(*[iter(iterable)]*chunksize, fillvalue=filler)

وأنا في حاجة إلى حل من شأنه أن يعمل أيضا مع مجموعات والمولدات الكهربائية. لم أتمكن من الخروج مع أي شيء قصير جدا وجميلة، لكنه مقروء جدا على الأقل.

def chunker(seq, size):
    res = []
    for el in seq:
        res.append(el)
        if len(res) == size:
            yield res
            res = []
    if res:
        yield res

وقائمة:

>>> list(chunker([i for i in range(10)], 3))
[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]

وتعيين:

>>> list(chunker(set([i for i in range(10)]), 3))
[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]

والمولدات:

>>> list(chunker((i for i in range(10)), 3))
[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]

وعلى غرار مقترحات أخرى، ولكن ليست متطابقة تماما، وأنا أحب القيام به على هذا النحو، لأنها بسيطة وسهلة لقراءة:

it = iter([1, 2, 3, 4, 5, 6, 7, 8, 9])
for chunk in zip(it, it, it, it):
    print chunk

>>> (1, 2, 3, 4)
>>> (5, 6, 7, 8)

وهذه الطريقة سوف لن تحصل على قطعة جزئية الماضية. إذا كنت ترغب في الحصول على (9, None, None, None) كما قطعة الماضية، ومجرد استخدام izip_longest من itertools.

والحل المثالي لهذه المشكلة يعمل مع مكررات (وليس تسلسل فقط). وينبغي أيضا أن تكون سريعة.

وهذا هو الحل التي قدمتها وثائق itertools:

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

وعن طريق %timeit ipython على بلدي ماك كتاب الجوية، وأحصل على 47.5 لنا في الحلقة.

ولكن، هذا حقا لا يعمل بالنسبة لي منذ ومبطن النتائج إلى أن المجموعات حتى الحجم. حل دون الحشو قليلا أكثر تعقيدا. الحل الأكثر السذاجة قد يكون:

def grouper(size, iterable):
    i = iter(iterable)
    while True:
        out = []
        try:
            for _ in range(size):
                out.append(i.next())
        except StopIteration:
            yield out
            break

        yield out

وبسيط، لكنه بطيء جدا: 693 لنا في حلقة

وأفضل حل أتمكن من الخروج مع استخدامات islice للحلقة الداخلية:

def grouper(size, iterable):
    it = iter(iterable)
    while True:
        group = tuple(itertools.islice(it, None, size))
        if not group:
            break
        yield group

ومع نفس مجموعة البيانات، وأحصل على 305 لنا في الحلقة.

وغير قادر على الحصول على حل النقي أي أسرع من ذلك، وتوفير الحل التالي مع تحذير هام: إذا كان إدخال البيانات لديه حالات filldata في ذلك، هل يمكن الحصول على إجابة خاطئة

def grouper(n, iterable, fillvalue=None):
    #"grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"
    args = [iter(iterable)] * n
    for i in itertools.izip_longest(fillvalue=fillvalue, *args):
        if tuple(i)[-1] == fillvalue:
            yield tuple(v for v in i if v != fillvalue)
        else:
            yield i

وأنا حقا لا أحب هذه الإجابة، وإنما هو أسرع بكثير. 124 لنا في حلقة

ومنذ أن ذكر أحد حتى الآن هنا هو حل zip():

>>> def chunker(iterable, chunksize):
...     return zip(*[iter(iterable)]*chunksize)

وأنها لا تعمل إلا إذا طول التسلسل الخاص بك هو دائما القسمة على حجم قطعة أو أنك لا يهتمون قطعة زائدة إذا لم يكن.

مثال:

>>> s = '1234567890'
>>> chunker(s, 3)
[('1', '2', '3'), ('4', '5', '6'), ('7', '8', '9')]
>>> chunker(s, 4)
[('1', '2', '3', '4'), ('5', '6', '7', '8')]
>>> chunker(s, 5)
[('1', '2', '3', '4', '5'), ('6', '7', '8', '9', '0')]

itertools.izip لإرجاع مكرر بدلا من القائمة:

>>> from itertools import izip
>>> def chunker(iterable, chunksize):
...     return izip(*[iter(iterable)]*chunksize)

ويمكن ان تكون ثابتة الحشو باستخدام <لأ href = "https://stackoverflow.com/questions/312443/how-do-you-split-a-list-into-evenly-sized-chunks-in-python#312644 "> @ ΤΖΩΤΖΙΟΥ في الإجابة :

>>> from itertools import chain, izip, repeat
>>> def chunker(iterable, chunksize, fillvalue=None):
...     it   = chain(iterable, repeat(fillvalue, chunksize-1))
...     args = [it] * chunksize
...     return izip(*args)

وعن طريق الخريطة () بدلا من الرمز () على إصلاح المشكلة الحشو في الإجابة J.F. سيباستيان:

>>> def chunker(iterable, chunksize):
...   return map(None,*[iter(iterable)]*chunksize)

مثال:

>>> s = '1234567890'
>>> chunker(s, 3)
[('1', '2', '3'), ('4', '5', '6'), ('7', '8', '9'), ('0', None, None)]
>>> chunker(s, 4)
[('1', '2', '3', '4'), ('5', '6', '7', '8'), ('9', '0', None, None)]
>>> chunker(s, 5)
[('1', '2', '3', '4', '5'), ('6', '7', '8', '9', '0')]

إذا كنت لا تمانع في استخدام حزمة الخارجية التي يمكن استخدامها iteration_utilities.grouper من iteration_utilties <سوب> 1 . وهو يدعم كل iterables (متواليات ليس فقط):

from iteration_utilities import grouper
seq = list(range(20))
for group in grouper(seq, 4):
    print(group)

والذي يطبع:

(0, 1, 2, 3)
(4, 5, 6, 7)
(8, 9, 10, 11)
(12, 13, 14, 15)
(16, 17, 18, 19)

في حالة طول ليست متعددة من groupsize كما أنها تدعم ملء (المجموعة الأخيرة غير مكتملة) أو اقتطاع (التخلص من المجموعة الأخيرة غير مكتملة) آخر واحد:

from iteration_utilities import grouper
seq = list(range(17))
for group in grouper(seq, 4):
    print(group)
# (0, 1, 2, 3)
# (4, 5, 6, 7)
# (8, 9, 10, 11)
# (12, 13, 14, 15)
# (16,)

for group in grouper(seq, 4, fillvalue=None):
    print(group)
# (0, 1, 2, 3)
# (4, 5, 6, 7)
# (8, 9, 10, 11)
# (12, 13, 14, 15)
# (16, None, None, None)

for group in grouper(seq, 4, truncate=True):
    print(group)
# (0, 1, 2, 3)
# (4, 5, 6, 7)
# (8, 9, 10, 11)
# (12, 13, 14, 15)

<سوب> 1 تنويه: أنا مؤلف تلك الحزمة

وإذا كانت القائمة كبيرة، وسوف الطريق أعلى أداء للقيام بذلك هو استخدام مولد:

def get_chunk(iterable, chunk_size):
    result = []
    for item in iterable:
        result.append(item)
        if len(result) == chunk_size:
            yield tuple(result)
            result = []
    if len(result) > 0:
        yield tuple(result)

for x in get_chunk([1,2,3,4,5,6,7,8,9,10], 3):
    print x

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

وظائف عن طريق والأشياء الصغيرة حقا لا يروق لي. أنا أفضل أن مجرد استخدام شرائح:

data = [...]
chunk_size = 10000 # or whatever
chunks = [data[i:i+chunk_size] for i in xrange(0,len(data),chunk_size)]
for chunk in chunks:
    ...

وثمة نهج آخر يتمثل في استخدام النموذج يومين حجة iter:

from itertools import islice

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

ويمكن تكييف هذا بسهولة استخدام الحشو (هذا هو مماثل ل الصورة الجواب ماركوس Jarderot ):

from itertools import islice, chain, repeat

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

وحتى يمكن الجمع بين هذه لالحشو اختياري:

_no_pad = object()
def group(it, size, pad=_no_pad):
    if pad == _no_pad:
        it = iter(it)
        sentinel = ()
    else:
        it = chain(iter(it), repeat(pad))
        sentinel = (pad,) * size
    return iter(lambda: tuple(islice(it, size)), sentinel)

ومع نمباي انها بسيطة:

ints = array([1, 2, 3, 4, 5, 6, 7, 8])
for int1, int2 in ints.reshape(-1, 2):
    print(int1, int2)

والإخراج:

1 2
3 4
5 6
7 8

وإذا لم يفتقد شيئا، لم يرد ذكرها الحل بسيط التالية مع تعبيرات المولد. ويفترض أن <م> ومن المعروف أن كلا من حجم وعدد قطع (والذي هو في كثير من الحالات)، وأنه لا الحشو مطلوب:

def chunks(it, n, m):
    """Make an iterator over m first chunks of size n.
    """
    it = iter(it)
    # Chunks are presented as tuples.
    return (tuple(next(it) for _ in range(n)) for _ in range(m))

في الطريقة الثانية الخاصة بك، وأود أن تقدم إلى المجموعة التالية من 4 عن طريق القيام بذلك:

ints = ints[4:]

ولكن، أنا لم تفعل أي قياس الأداء لذلك أنا لا أعرف أي واحد قد يكون أكثر كفاءة.

وأما وقد قلت ذلك، وأود أن تختار عادة الأسلوب الأول. انها ليست جميلة، ولكن هذا في كثير من الأحيان نتيجة للتفاعل مع العالم الخارجي.

بعد إجابة أخرى, مزايا منها:

1) مفهومة بسهولة
2) يعمل على أي iterable ليس مجرد تسلسل (بعض من الإجابات أعلاه سوف تختنق filehandles)
3) لا يتم تحميل جزء في الذاكرة في كل مرة
4) لا تجعل قطعة-قائمة طويلة من المراجع نفسه مكرر في الذاكرة
5) لا الحشو من ملء القيم في نهاية القائمة

أن يقال, لم توقيت ذلك قد يكون أبطأ من بعض من أكثر أساليب ذكية و بعض المزايا قد تكون ذات صلة بالنظر إلى حالة استخدام.

def chunkiter(iterable, size):
  def inneriter(first, iterator, size):
    yield first
    for _ in xrange(size - 1): 
      yield iterator.next()
  it = iter(iterable)
  while True:
    yield inneriter(it.next(), it, size)

In [2]: i = chunkiter('abcdefgh', 3)
In [3]: for ii in i:                                                
          for c in ii:
            print c,
          print ''
        ...:     
        a b c 
        d e f 
        g h 

تحديث:
زوجين من العيوب يرجع ذلك إلى حقيقة الداخلي والخارجي الحلقات سحب القيم من نفس التكرار:
1) مواصلة لا يعمل كما هو متوقع في الحلقة الخارجية - إنه لا يزال مجرد يوم إلى البند التالي بدلا من تخطي قطعة.غير أن هذا لا يبدو وكأنه مشكلة كما لا يوجد اختبار في الحلقة الخارجية.
2) كسر لا يعمل كما هو متوقع في الحلقة الداخلية - التحكم سوف تصل الرياح في الحلقة الداخلية مرة أخرى مع البند التالي في التكرار.لتخطي كل قطع, إما التفاف الداخلية مكرر (ثانيا) في المجموعة, على سبيل المثال for c in tuple(ii), أو تعيين إشارة العادم مكرر.

def group_by(iterable, size):
    """Group an iterable into lists that don't exceed the size given.

    >>> group_by([1,2,3,4,5], 2)
    [[1, 2], [3, 4], [5]]

    """
    sublist = []

    for index, item in enumerate(iterable):
        if index > 0 and index % size == 0:
            yield sublist
            sublist = []

        sublist.append(item)

    if sublist:
        yield sublist

ويمكنك استخدام التقسيم أو <وأ href = "HTTP: //funcy.readthedocs.org/en/latest/seqs.html#chunks "يختلط =" نوفولو "> قطع وظيفة من <لأ href =" https://github.com/Suor/funcy "يختلط = "نوفولو"> funcy مكتبة:

from funcy import partition

for a, b, c, d in partition(4, ints):
    foo += a * b * c * d

وله هذه الوظائف أيضا إصدارات مكرر ipartition وichunks، والتي سوف تكون أكثر كفاءة في هذه القضية.

ويمكنك أيضا نظرة خاطفة على تنفيذها .

لتجنب كل التحويلات إلى قائمة import itertools و:

>>> for k, g in itertools.groupby(xrange(35), lambda x: x/10):
...     list(g)

وتنتج:

... 
0 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
1 [10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
2 [20, 21, 22, 23, 24, 25, 26, 27, 28, 29]
3 [30, 31, 32, 33, 34]
>>> 

وراجعت groupby وأنها لا تتحول إلى قائمة أو استخدام len ذلك (اعتقد) سيؤدي ذلك إلى تأخير حل كل قيمة حتى يتم استخدامه في الواقع. للأسف لا شيء من الأجوبة المتاحة (في هذا الوقت) ويبدو أن تقديم هذا الاختلاف.

من الواضح إذا كنت بحاجة إلى التعامل مع كل عنصر بدوره عش للحلقة على ز:

for k,g in itertools.groupby(xrange(35), lambda x: x/10):
    for i in g:
       # do what you need to do with individual items
    # now do what you need to do with the whole group

وكان اهتمامي محددة في هذا الحاجة إلى تستهلك مولد لتقديم التغييرات على دفعات تصل إلى 1000 إلى API جوجل:

    messages = a_generator_which_would_not_be_smart_as_a_list
    for idx, batch in groupby(messages, lambda x: x/1000):
        batch_request = BatchHttpRequest()
        for message in batch:
            batch_request.add(self.service.users().messages().modify(userId='me', id=message['id'], body=msg_labels))
        http = httplib2.Http()
        self.credentials.authorize(http)
        batch_request.execute(http=http)

وعن حل أعطى من قبل J.F. Sebastian هنا :

def chunker(iterable, chunksize):
    return zip(*[iter(iterable)]*chunksize)

وانها ذكية، ولكن لديه عيب واحد - دائما العودة الصفوف (tuple). كيفية الحصول على سلسلة بدلا منتديات بالطبع يمكنك كتابة ''.join(chunker(...))، ولكن يتم إنشاء الصفوف (tuple) مؤقتة على أي حال.

ويمكنك التخلص من الصفوف (tuple) مؤقتة عن طريق الكتابة zip الخاصة، مثل هذا:

class IteratorExhausted(Exception):
    pass

def translate_StopIteration(iterable, to=IteratorExhausted):
    for i in iterable:
        yield i
    raise to # StopIteration would get ignored because this is generator,
             # but custom exception can leave the generator.

def custom_zip(*iterables, reductor=tuple):
    iterators = tuple(map(translate_StopIteration, iterables))
    while True:
        try:
            yield reductor(next(i) for i in iterators)
        except IteratorExhausted: # when any of iterators get exhausted.
            break

ثم

def chunker(data, size, reductor=tuple):
    return custom_zip(*[iter(data)]*size, reductor=reductor)

والاستخدام مثال:

>>> for i in chunker('12345', 2):
...     print(repr(i))
...
('1', '2')
('3', '4')
>>> for i in chunker('12345', 2, ''.join):
...     print(repr(i))
...
'12'
'34'

وأنا أحب هذا النهج. تشعر أنها بسيطة وليس سحري ويدعم جميع أنواع iterable ولا يتطلب الواردات.

def chunk_iter(iterable, chunk_size):
it = iter(iterable)
while True:
    chunk = tuple(next(it) for _ in range(chunk_size))
    if not chunk:
        break
    yield chunk

وأنا لا أريد بلدي قطع مبطن، لذلك هذا الشرط ضروري. أجد أن القدرة على العمل في أي iterable هي أيضا شرط. بالنظر إلى ذلك، قررت تمديد على الاجابة المقبولة، https://stackoverflow.com/a/434411/1074659 .

والأداء يأخذ ضربة طفيفة في هذا النهج إذا لم يتم أراد الحشو الواجب لضرورة لمقارنة وتصفية القيم مبطن. ومع ذلك، لأحجام جزء كبير، هذه الأداة هي performant للغاية.

#!/usr/bin/env python3
from itertools import zip_longest


_UNDEFINED = object()


def chunker(iterable, chunksize, fillvalue=_UNDEFINED):
    """
    Collect data into chunks and optionally pad it.

    Performance worsens as `chunksize` approaches 1.

    Inspired by:
        https://docs.python.org/3/library/itertools.html#itertools-recipes

    """
    args = [iter(iterable)] * chunksize
    chunks = zip_longest(*args, fillvalue=fillvalue)
    yield from (
        filter(lambda val: val is not _UNDEFINED, chunk)
        if chunk[-1] is _UNDEFINED
        else chunk
        for chunk in chunks
    ) if fillvalue is _UNDEFINED else chunks
def chunker(iterable, n):
    """Yield iterable in chunk sizes.

    >>> chunks = chunker('ABCDEF', n=4)
    >>> chunks.next()
    ['A', 'B', 'C', 'D']
    >>> chunks.next()
    ['E', 'F']
    """
    it = iter(iterable)
    while True:
        chunk = []
        for i in range(n):
            try:
                chunk.append(next(it))
            except StopIteration:
                yield chunk
                raise StopIteration
        yield chunk

if __name__ == '__main__':
    import doctest

    doctest.testmod()

وهنا هو chunker دون الواردات التي تدعم المولدات:

def chunks(seq, size):
    it = iter(seq)
    while True:
        ret = tuple(next(it) for _ in range(size))
        if len(ret) == size:
            yield ret
        else:
            raise StopIteration()

ومثال على الاستخدام:

>>> def foo():
...     i = 0
...     while True:
...         i += 1
...         yield i
...
>>> c = chunks(foo(), 3)
>>> c.next()
(1, 2, 3)
>>> c.next()
(4, 5, 6)
>>> list(chunks('abcdefg', 2))
[('a', 'b'), ('c', 'd'), ('e', 'f')]

وهناك لا يبدو أن يكون وسيلة جميلة للقيام بذلك. هنا : عبارة عن صفحة التي تحتوي على عدد من الطرق، بما في ذلك:

def split_seq(seq, size):
    newseq = []
    splitsize = 1.0/size*len(seq)
    for i in range(size):
        newseq.append(seq[int(round(i*splitsize)):int(round((i+1)*splitsize))])
    return newseq

إذا القوائم هي نفس الحجم، يمكنك الجمع بينهما في قوائم 4 الصفوف مع zip(). على سبيل المثال:

# Four lists of four elements each.

l1 = range(0, 4)
l2 = range(4, 8)
l3 = range(8, 12)
l4 = range(12, 16)

for i1, i2, i3, i4 in zip(l1, l2, l3, l4):
    ...

وإليك ما تنتج وظيفة zip():

>>> print l1
[0, 1, 2, 3]
>>> print l2
[4, 5, 6, 7]
>>> print l3
[8, 9, 10, 11]
>>> print l4
[12, 13, 14, 15]
>>> print zip(l1, l2, l3, l4)
[(0, 4, 8, 12), (1, 5, 9, 13), (2, 6, 10, 14), (3, 7, 11, 15)]

إذا القوائم كبيرة، وكنت لا ترغب في الجمع بينهما في قائمة أكبر، استخدم itertools.izip()، التي تنتج مكرر، بدلا من القائمة.

from itertools import izip

for i1, i2, i3, i4 in izip(l1, l2, l3, l4):
    ...

والخطوط الملاحية المنتظمة واحد، حل مخصصا لأعاد على x قائمة في أجزاء من حجم 4 -

for a, b, c, d in zip(x[0::4], x[1::4], x[2::4], x[3::4]):
    ... do something with a, b, c and d ...

في البداية ، لم تهدف إلى تقسيم الجمل إلى سلاسل فرعية لتحليل سلسلة تحتوي عرافة.
اليوم والتفت إلى معقدة ، ولكن لا يزال مولد بسيط.

def chunker(iterable, size, reductor, condition):
    it = iter(iterable)
    def chunk_generator():
        return (next(it) for _ in range(size))
    chunk = reductor(chunk_generator())
    while condition(chunk):
        yield chunk
        chunk = reductor(chunk_generator())

الحجج:

منها واضحة

  • iterable أي iterable / مكرر / مولد containg / توليد / بالتكرار على إدخال البيانات ،
  • size بالطبع حجم قطعة تريد الحصول عليها ،

أكثر إثارة للاهتمام

  • reductor هو للاستدعاء الذي يتلقى مولد بالتكرار على محتوى قطعة.
    أتوقع أن يعود تسلسل أو سلسلة, ولكن أنا لا أطالب بذلك.

    يمكنك تمرير مثل هذه الحجة على سبيل المثال list, tuple, set, frozenset,
    أو أي شيء مربي الحيوانات.أود أن تمر هذه الدالة تعود السلسلة
    (شريطة أن iterable يحتوي على / تولد / تتكرر على السلاسل):

    def concatenate(iterable):
        return ''.join(iterable)
    

    علما بأن reductor يمكن أن يسبب إغلاق مولد خلال رفع استثناء.

  • condition هو للاستدعاء الذي يحصل أي شيء ما reductor عاد.
    أنه تقرر الموافقة على & العائد عليه (من خلال العودة شيئا تقييم True),
    أو لرفضه & الانتهاء من المولد العمل (من خلال العودة أي شيء آخر أو رفع استثناء).

    عندما يكون عدد العناصر في iterable هو لا يقبل القسمة size, عندما it يحصل استنفدت ، reductor سوف تتلقى مولد توليد أقل عناصر من size.
    دعونا نطلق على هذه العناصر يستمر عناصر.

    دعوت وظيفتين لتمرير مثل هذه الحجة:

    • lambda x:x ـ يستمر عناصر وبالتالى يتم.

    • lambda x: len(x)==<size> ـ يستمر عناصر سيتم رفض.
      محل <size> باستخدام عدد يساوي size

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top