الكر

إن الكر (Iteration) من أكثر العمليات استعمالاً في البرمجة عمومًا. وقد خُصِّصَ لها في بايثون كائنان:

الأول: المكرور (Iterable) ما يُنتج عنصرًا في كل كرة. مثلُ الكتابِ؛ فهو لا يقلب صفحاته بنفسه. لكن عنده مفهوم التوالي.

الثاني: الكار (Iterator) ما يحفظ مكانه، ويعطي ما بعده. مثلُ العلامة أو البطاقة التي توضع في الكتاب.

العلاقة بين الكار والمكرور هي علاقة الفاعل بالمفعول. فكل مكرور، عند تنفيذ الكر عليه فإن بايثون تُنشئ له كارًّا لتأتي على عناصره في الحلقة مثلًا.

وجملة الكر هي المبتدأة بكلمة for على هذا النحو:

for item in iterable:
    print(item)

وهذه شجرة توضح العلاقة بين الكائنات التي تقبل الكر في بايثون:

classDiagram

    class Iterable {
        <<abstract>>
        +__iter__()
    }

    class Collection {
        <<abstract>>
    }

    class Iterator {
        <<abstract>>
        +__next__()
    }

    Iterable <|-- Iterator
    Iterable <|-- Collection

    Collection <|-- list
    Collection <|-- tuple
    Collection <|-- dict
    Collection <|-- str
    Collection <|-- range

المكرور

فالقائمة (list) سلسلة، والسلسلة من الجمع، والجمع مكرور.

my_list = [1, 2, 3]
for item in my_list:
    print(item)

والصف (tuple) سلسلة، والسلسلة من الجمع، والجمع مكرور.

my_tuple = (1, 2, 3)
for item in my_tuple:
    print(item)

والنص (str): سلسلة أحرف، والسلسلة من الجمع، والجمع مكرور.

my_string = "abc"
for character in my_string:
    print(character)

والقاموس: جمع، والجمع مكرور (dict).

my_dict = {
    'one': 100,
    'two': 200,
    'three': 300,
}
for key, value in my_dict.items():
    print(key, value)

والنطاق (range): جمع وهو مكرور.

for number in range(3):
    print(number)

الكار

الكار: عارض. بمعنى أنه يوجَد مرة ويستهلَك، ثم نحتاج إلى كار جديد لمعاودة الكر. أما المكرور فهو الشيء القابل لعملية الكر.

فالملف (file object): كار. حيث ينتهي الكر بوصول مؤشر القراءة لآخر سطر في الملف.

my_file = open("myfile.txt")
for line in my_file:
    print(line)
my_file.close()

مسالك معروفة في الكر

لا يلزم أن يسلك الكار طريقًا مستقيمًا على المكرور؛ بل قد يكون بأي منطق نريد.

وقد تم تعريف طرائق في الكر يكثر استعمالها على المكرورات. فمنها ما في الحزمة itertools.

مثل التباديل (permutations): وهي جميع الاحتمالات الممكنة لترتيب عناصر المجموعة:

from itertools import permutations

perms = permutations('بحر')

for p in perms:
    print(p)

والتوافيق(combinations) وهي اختيار العناصر الفريدة بغض النظر عن ترتيبها:

from itertools import combinations

players = ['Ahmad', 'Belal', 'Camal']

combs = combinations(players, 2)

for c in combs:
    print(c)

وكذلك الضرب(product) على هذا النحو:

from itertools import product

colors = ['red', 'blue']
sizes = ['S', 'M']

prod = product(colors, sizes)

for p in prod:
    print(p)

وغيرها تجدها في المكتبة الأساسية في بايثون.

المولد

ومن المكرِّرات: المولِّد (Generator) وهي دوال قابلة للكر. ويلاحظ وجوع كلمة yield بدلاً من كلمة return لإنتاج القيَم، على النحو التالي:

def my_generator():
    yield 1
    yield 2
    yield 3

for number in my_generator():
    print(number)

مثال ذلك:

def reverse(data):
    for index in range(len(data)-1, -1, -1):
        yield data[index]

for char in reverse('golf'):
    print(char)