الدالة zip()‎ في بايثون

من موسوعة حسوب

تعيد الدّالة zip()‎ مُكرّرًا يُركّب عناصر كلّ من الكائنات القابلة للتّكرار المُعطاة.

البنية العامة

zip(*iterables)

المعاملات

iterables

مُعامل اختياريّ يُمثّل الكائنات القابلة للتّكرار المرغوب تركيبها.

القيمة المعادة

مُكرّر يحتوي على صفوف تكون عناصرها ذات نفس الفهرس (index) في كلّ عنصر من عناصر الكائنات القابلة للتّكرار. إذ يحتوي مثلا أول صفّ على جميع العناصر التي تكون أول العناصر في الكائنات القابلة للتّكرار المُعطاة (انظر الأمثلة أدناه).

يتوقّف المُكرّر عندما تنتهي عناصر أصغر كائن قابل للتّكرار.

عند استدعائها بكائن واحد قابل للتّكرار فقط، فستُعيد الدّالة مُكرّرًا يحتوي على صفوف من عنصر واحد فقط.

إن لم تُمرّر للدّالة أية مُعاملات، فسيُعاد مُكرّر فارغ.

أمثلة

المثال التّالي يوضّح كيفيّة عمل هذه الدّالة، نستعمل الدّالة list()‎ لعرض ما بداخل المُكرّر النّاتج:

>>> list(zip([1, 2, 3], 'abc'))
[(1, 'a'), (2, 'b'), (3, 'c')]
>>> list(zip([1, 2, 3], 'abcdfe')) # تُتجاهل القيم الزّائدة
[(1, 'a'), (2, 'b'), (3, 'c')]
>>> list(zip([1, 2, 3], (1, 2, 3))) # تركيب قائمة وصفّ
[(1, 1), (2, 2), (3, 3)]
>>> list(zip([1, 2, 3], range(1, 4))) # تركيب قائمة وكائن مجال 
[(1, 1), (2, 2), (3, 3)]

يُمكن مثلا استخدام الدّالة zip()‎ مع الدّالة dict()‎ لإنشاء قاموس من كائنين قابلين للتّكرار تكون مفاتيحه من الكائن الأول وقيمها من الكائن الثّاني:

>>> dict(zip("abc", range(3)))
{'a': 0, 'b': 1, 'c': 2}

ملاحظات

الدّالة zip()‎ مُكافئةٌ لما يلي:

def zip(*iterables):
    # zip('ABCD', 'xy') --> Ax By
    sentinel = object()
    iterators = [iter(it) for it in iterables]
    while iterators:
        result = []
        for it in iterators:
            elem = next(it, sentinel)
            if elem is sentinel:
                return
            result.append(elem)
        yield tuple(result)

تُقدَّر الكائنات القابلة للتّكرار من اليسار إلى اليمين دائمًا. ما يسمح بتركيب سلاسل بيانات إلى مجموعات مُحدّدة الطّول باستخدام الاستدعاء zip‎(‎*‎[‎iter‎(‎s‎)‎]‎*‎n‎)‎. ما يُعيد نفس المُكرّر عدد n مرّات لكي يحتوي كلّ صفّ على نتيجة استدعاء المكرّر n مرّات. ما يسمح بتقسيم المُدخل إلى أجزاء طولها n. على سبيل المثال، سيحتوي المُكرّر النّاتج من الاستدعاء ‎zip‎(‎*‎[iter‎(range‎(10‎‎)‎)‎]‎*‎2)‎ الصّفوف التّالية:

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

لا تستخدم الدّالة zip‎()‎ إلّا إن كانت المُدخلات ذات طول مُتساوٍ أو إن لم تكن القيم المتبقيّة في الكائن القابل للتّكرار الأطول مُهمّة. إن كانت هذه القيم مُهمّة، فاستعمال الدّالة itertools.zip_longest عوضًا عنها، إذ تُبقي هذه الأخيرة على القيم الزّائدة وتُركّبها مع القيمة None‎ كما يلي:

>>> itertools.zip_longest(range(3), 'abcdef')
<itertools.zip_longest object at 0x7fd60f1e8bd8>

>>> list(itertools.zip_longest(range(3), 'abcdef'))
[(0, 'a'), (1, 'b'), (2, 'c'), (None, 'd'), (None, 'e'), (None, 'f')]

يُمكن استعمال الدّالة zip‎()‎ مع العامل * لفكّ التّركيب:

>>> x = [1, 2, 3]
>>> y = [4, 5, 6]
>>> zipped = zip(x, y)
>>> list(zipped)
[(1, 4), (2, 5), (3, 6)]
>>> x2, y2 = zip(*zip(x, y))
>>> x == list(x2) and y == list(y2)
True

انظر أيضًا

مصادر