ال

الحلقات في Python

93 تمرينًا

نبذة عن الحلقات

تحتوي Python على تركيبين للتكرار. حلقات while للتكرار غير المحدد (غير المعدود)، وحلقات for للتكرار المحدد (المعدود). وتساعد الكلمات المفتاحية break وcontinue وelse على تخصيص سلوك الحلقة. وتساعد range() وenumerate() في عدّ الحلقة والفهرسة.

حلقة while

تستمر حلقات loop في التنفيذ ما دام loop expression أو "الاختبار" يُقيَّم إلى True في boolean context، وتنتهي عندما يُقيَّم إلى False:

# Lists are considered "truthy" in a boolean context if they
# contain one or more values, and "falsy" if they are empty.

>>> placeholders = ["spam", "ham", "eggs", "green_spam", "green_ham", "green_eggs"]

>>> while placeholders:
...     print(placeholders.pop(0))
...
'spam'
'ham'
'eggs'
'green_spam'
'green_ham'
'green_eggs'

حلقة for

الوصف الأدق لحلقة stop الأساسية في Python أنها حلقة for each تمر على قيم أي كائن قابل للتكرار، وتتوقف عندما لا تُرجَع أي قيم عند استدعاء next() (برفع StopIteration).

>>> word_list = ["bird", "chicken", "barrel", "bongo"]

>>> for word in word_list:
...    if word.startswith("b"):
...        print(f"{word.title()} starts with a B.")
...    else:
...        print(f"{word.title()} doesn't start with a B.")
...
'Bird starts with a B.'
'Chicken doesn\'t start with a B.'
'Barrel starts with a B.'
'Bongo starts with a B.'

كائن التسلسل range()

عندما لا يوجد iterable محدد، يُستخدم التسلسل الخاص range() كعدّاد للحلقة. تتطلب range() قيمة من النوع int يتوقف عندها التسلسل، ويمكنها اختياريًا أن تأخذ المعاملين start وstep. إذا لم يُحدَّد رقم start، فسيبدأ التسلسل من 0. كائنات range() كسولة (تُولَّد القيم عند الطلب)، وتدعم كل عمليات التسلسل الشائعة، وتستهلك مقدارًا ثابتًا من الذاكرة، مهما طال التسلسل المحدد. ومن المثير للاهتمام أن range() ليست مكرِّرًا، ويمكن استخدامها في سياقات كثيرة لا تتضمن حلقات عندما نحتاج إلى تسلسل من الأعداد.

# Here we use range to produce some numbers, rather than creating a list of them in memory.
# The values will start with 1 and stop *before* 7.

>>> for number in range(1, 7):
...    if number % 2 == 0:
...       print(f"{number} is even.")
...    else:
...       print(f"{number} is odd.")
'1 is odd.'
'2 is even.'
'3 is odd.'
'4 is even.'
'5 is odd.'
'6 is even.'

# range() can also take a *step* parameter.
# Here we use range to produce only the "odd" numbers, starting with 3 and stopping *before* 15.

>>> for number in range(3, 15, 2):
...    if number % 2 == 0:
...       print(f"{number} is even.")
...    else:
...       print(f"{number} is odd.")
...
'3 is odd.'
'5 is odd.'
'7 is odd.'
'9 is odd.'
'11 is odd.'
'13 is odd.'

القيم والفهارس باستخدام enumerate()

إذا احتجت إلى القيم والفهارس معًا، فإن الدالة المدمجة enumerate(<iterable>) ستُرجع iterator على أزواج (index, value):

>>> word_list = ["bird", "chicken", "barrel", "apple"]

# *index* and *word* are the loop variables.
# Loop variables can be any valid python name.

>>> for index, word in enumerate(word_list):
...    if word.startswith("b"):
...        print(f"{word.title()} (at index {index}) starts with a B.")
...    else:
...        print(f"{word.title()} (at index {index}) doesn't start with a B.")
...
'Bird (at index 0) starts with a B.'
'Chicken (at index 1) doesn\'t start with a B.'
'Barrel (at index 2) starts with a B.'
'Apple (at index 3) doesn\'t start with a B.'


# The same method can be used as a "lookup" for pairing items between two lists.
# Of course, if the lengths or indexes don't line up, this doesn't work.

>>> word_list = ["cat", "chicken", "barrel", "apple", "spinach"]
>>> category_list = ["mammal", "bird", "thing", "fruit", "vegetable"]

>>> for index, word in enumerate(word_list):
...    print(f"{word.title()} is in category: {category_list[index]}.")
...
'Cat is in category: mammal.'
'Chicken is in category: bird.'
'Barrel is in category: thing.'
'Apple is in category: fruit.'
'Spinach is in category: vegetable.'

يمكن أيضًا ضبط الدالة enumerate(<iterable>) بحيث يبدأ عدّ الفهرس من رقم مختلف عبر start:

# Here, the index count will start at 1.
>>> for position, word in enumerate(word_list, start=1):
...    if word.startswith("b"):
...        print(f"{word.title()} (at position {position}) starts with a B.")
...    else:
...        print(f"{word.title()} (at position {position}) doesn't start with a B.")
...
'Bird (at position 1) starts with a B.'
'Chicken (at position 2) doesn\'t start with a B.'
'Barrel (at position 3) starts with a B.'
'Apple (at position 4) doesn\'t start with a B.'

تغيير سلوك الحلقة

يمكن استخدام الكلمة المفتاحية continue للانتقال مباشرة إلى دورة التكرار التالية:

>>> word_list = ["bird", "chicken", "barrel", "bongo", "sliver", "apple", "bear"]
...
... # This will skip *bird*, at index 0
... for index, word in enumerate(word_list):
...     if index == 0:
...         continue
...     if word.startswith("b"):
...         print(f"{word.title()} (at index {index}) starts with a b.")
...
'Barrel (at index 2) starts with a b.'
'Bongo (at index 3) starts with a b.'
'Bear (at index 6) starts with a b.'

يمكن استخدام الكلمة المفتاحية break (كما في كثير من اللغات المتفرعة من C) لإيقاف التكرار و"الخروج" من loop الأعمق المحيطة:

>>>  word_list = ["bird", "chicken", "barrel", "bongo", "sliver", "apple"]

>>> for index, word in enumerate(word_list):
...    if word.startswith("b"):
...        print(f"{word.title()} (at index {index}) starts with a B.")
...    elif word == "sliver":
...        break
...    else:
...        print(f"{word.title()} doesn't start with a B.")
... print("loop broken.")
...
'Bird (at index 0) starts with a B.'
'Chicken doesn\'t start with a B.'
'Barrel (at index 2) starts with a B.'
'Bongo (at index 3) starts with a B.'
'loop broken.'

بند else في الحلقة فريد من نوعه في Python، ويمكن استخدامه لأفعال "الختام" أو "الإنهاء" عند نفاد التكرار. لا تُنفَّذ العبارات التي تلي الكلمة المفتاحية else إذا انتهى التكرار عبر break:

>>> word_list = ["bird", "chicken", "barrel", "bongo", "sliver", "apple"]

# Using enumerate to get both an index and a value.

>>> for index, word in enumerate(word_list):
...    word = word.title()
...    if word.startswith("B"):
...        print(f"{word} (at index {index}) starts with a B.")
...
... # This executes once *StopIteration* is raised and 
... # There are no more items to iterate through.
... # Note the indentation, which lines up with the for keyword.
... else:
...    print(f"Found the above b-words, out of {len(word_list)} words in the word list.")
...
'Bird (at index 0) starts with a B.'
'Barrel (at index 2) starts with a B.'
'Bongo (at index 3) starts with a B.'
'Found the above b-words, out of 6 words in the word list.'


# Terminating a loop via *break* will bypass the loop *else* clause

>>> for index, word in enumerate(word_list):
...    word = word.title()
...    if word.startswith("B"):
...       print(f"{word} (at index {index}) starts with a B.")
...    if word.startswith("S"):
...        print("Found an S, stopping iteration.")
...        break

... # This statement does not run, because a *break* was triggered.
... else:
...    print(f"Found the above b-words, out of {len(word_list)} words in the word list.")
...
'Bird (at index 0) starts with a B.'
'Barrel (at index 2) starts with a B.'
'Bongo (at index 3) starts with a B.'
'Found an S, stopping iteration.'
تعديل عبر GitHub يفتح الرابط في نافذة أو علامة تبويب جديدة

تعلّم الحلقات

التدريب مقفل

افتح 6 تمارين إضافية لممارسة الحلقات