مقدمة إلى الحلقات المتداخلة (Nested Loops)
رأيت من قبل أن الجسم المزاح داخل if أو داخل حلقة يمكن أن يحتوي على أي نوع من التعليمات، بما في ذلك شروط if أخرى أو حلقات أخرى. وبالتحديد، يمكن أن توجد حلقة داخل حلقة.
إليك مثالًا:
for letter in 'ABC':
print(letter)
for number in range(4):
print(f'{letter} {number}')
print('---')
هذا يسمى حلقة متداخلة (nested loop). لا توجد هنا قاعدة جديدة تمامًا؛ نحن فقط نركّب الأدوات التي تعرفها بالفعل. لكن من المهم أن تفهم هذا التركيب جيدًا لأنه مفيد جدًا في كتابة برامج أكثر تعقيدًا.
تأكد أولًا أنك تفهم ما يحدث. السطران print(letter) وprint('---') يعمل كل منهما 3 مرات، لأن مستوى الإزاحة الخاص بهما يضعهما داخل الحلقة الخارجية. أما print(f'{letter} {number}') فيعمل 3 × 4 = 12 مرة، لأنه داخل الحلقة الداخلية for number in range(4): التي تنفذ 4 دورات في كل دورة من دورات الحلقة الخارجية الثلاث.
لنستخدم الفكرة عمليًا. تخيل أنك مدرس وتريد طباعة جداول الضرب من 1 إلى 12 للطلاب. بدل كتابتها يدويًا، اكتب برنامجًا ينتجها كلها. يجب أن يكون الناتج بهذا الشكل، مع أسطر الشرطات بين الجداول:
1 x 1 = 1 1 x 2 = 2 1 x 3 = 3 1 x 4 = 4 1 x 5 = 5 1 x 6 = 6 1 x 7 = 7 1 x 8 = 8 1 x 9 = 9 1 x 10 = 10 1 x 11 = 11 1 x 12 = 12
2 x 1 = 2 2 x 2 = 4 2 x 3 = 6 2 x 4 = 8 2 x 5 = 10 2 x 6 = 12 2 x 7 = 14 2 x 8 = 16 2 x 9 = 18 2 x 10 = 20 2 x 11 = 22 2 x 12 = 24
3 x 1 = 3 3 x 2 = 6 3 x 3 = 9 (ويستمر النمط نفسه...) 11 x 10 = 110 11 x 11 = 121 11 x 12 = 132
12 x 1 = 12 12 x 2 = 24 12 x 3 = 36 12 x 4 = 48 12 x 5 = 60 12 x 6 = 72 12 x 7 = 84 12 x 8 = 96 12 x 9 = 108 12 x 10 = 120 12 x 11 = 132 12 x 12 = 144
You need to use a for loop inside a for loop.
You need the numbers from 1 to 12.
Whenever you need a sequence of consecutive numbers, use
range.You want something like
for x in range(n):.This will start with
x = 0, but there's an easy workaround for that.You can just add 1 to
x.Use
*to multiply numbers.Use an f-string with several variables.
Remember to print a line with the correct number of dashes after each section.
Make sure each line is in the correct loop and has the right amount of indentation.
ممتاز!
التمرين التالي: أنت تنظم بطولة للعبة مثل الشطرنج أو التنس، ولديك قائمة بأسماء اللاعبين:
players = ["Alice", "Bob", "Charlie"] سيلعب كل لاعب ضد كل لاعب آخر مرتين: مرة تكون له فيها أفضلية البداية مثل الحركة أو الإرسال أولًا، ومرة لا تكون له هذه الأفضلية. اطبع جميع المواجهات بهذا الشكل:
Alice vs Bob
Alice vs Charlie
Bob vs Alice
Bob vs Charlie
Charlie vs Alice
Charlie vs Bob
لاحظ أن Alice vs Bob وBob vs Alice موجودتان معًا، لكن لا توجد Alice vs Alice لأننا لا نريد أن يلعب أحد ضد نفسه.
Think about how you would do this manually and systematically, with a pencil and paper.
You need to use a for loop inside a for loop.
You need an
ifstatement to check that the two players aren't the same person.
في التمرين التالي ستولّد كل الاحتمالات الممكنة لكلمة مرور. أنت تعرف أنها تتكوّن من أربعة أحرف بالضبط، وأن الأحرف المحتملة محدودة ومخزنة هنا:
letters = "ABCD" اطبع كل كلمات المرور الممكنة:
AAAA
AAAB
AAAC
AAAD
AABA
AABB
... مع تخطي بعض الأسطر ...
DDDA
DDDB
DDDC
DDDD
فكّر في كل موضع من المواضع الأربعة على أنه اختيار مستقل من الأحرف الموجودة في letters.
Think about how you would do this manually and systematically, with a pencil and paper.
The fact that the password must be four letters long is very important. This would be a lot harder to solve if the password could be any given length.
But the string
lettersmight have any number of characters.If there are
ndifferent letters, then the number of possible passwords isn^4 == n*n*n*nbecause there arenpossible letters for each position and they're all independent.Suppose again that
letters = "ABCD". Imagine you have all possible three-letter passwords. Now for each one, add an A at the end, or add a B, or a C, or a D. That's how you would get all possible four-letter passwords.Remember, a for loop can contain any statement, including another for loop.
That applies to all for loops.
One for loop inside another for loop is no longer enough.
You have to go deeper.
أصبحت قريبًا من محترفي الاختراق الآن!
تمرين آخر. لديك حجم:
size = 5
اطبع مثلثًا «مقلوبًا» من علامة الجمع +، بحيث يكون طول ضلعه مساويًا للحجم المعطى. مثلًا يجب أن يكون الناتج:
+++++
++++
+++
++
+
فكّر في البرنامج على أنه يطبع أولًا سطرًا بطول size، ثم سطرًا أقصر بحرف واحد، ويستمر حتى يصل إلى حرف واحد.
How would you describe instructions to type in this triangle manually?
Print a line of
sizeplus signs, thensize - 1plus signs, etc. down to 1 plus sign. For example print 5+s, then 4+s, then 3, 2, and 1.Break this down into subproblems.
How do you print one line of
+s of a given length, and how do you go through all the lengths?Building up a line of characters should be very familiar from previous exercises, the only difference is that you have to make it a given length instead of just the same length as another string.
An easy way to do something
ntimes is to loop overrange(n).You need to use a for loop inside a for loop.
You need numbers that count down, like 5, 4, 3, 2, 1. There is a way to do this with
range, and you can easily look it up, but it's also easy to use a normal range and do some very simple maths to convert numbers counting up into numbers counting down.What formula converts 0 into 5, 1 into 4, 2 into 3, etc?
رائع، لديك حس فني أيضًا!
يمكنك الانتقال إلى الصفحة التالية الآن، أو حل تحدٍّ إضافي.
كما في تمرين البطولة السابق، لديك قائمة بأسماء اللاعبين:
players = ['Charlie', 'Alice', 'Dylan', 'Bob']
هذه المرة يجب أن يظهر كل زوج من اللاعبين مرة واحدة فقط. اطبع الأزواج بالترتيب نفسه من اليسار إلى اليمين كما تظهر الأسماء في players: ابدأ بالأزواج التي تحتوي على أول شخص في القائمة، ثم تحرك يمينًا. في المثال السابق يجب أن يطبع البرنامج:
Charlie vs Alice Charlie vs Dylan Charlie vs Bob Alice vs Dylan Alice vs Bob Dylan vs Bob أي إننا نطبع الزوج فقط عندما يأتي اللاعب الموجود على اليسار قبل اللاعب الموجود على اليمين في القائمة.
You'll need a for loop inside a for loop like before.
This time something like
for player1 in players:won't be enough.Your program needs to use the positions of the players in the list.
That means you need to loop over the positions and use indexing (subscripting) to access the list entries.
To loop over the positions, use
range......and
len.Look at the desired output:
Charlie vs Alice:Charliecomes beforeAlicein theplayerslist.We don't want to print
Alice vs CharliebecauseAlicecomes AFTERCharlieinplayers.The only pairs we want to print are those where the left player comes before the right player in the list.
How can we express this relation in terms of the list indices of the two for-loops?
You need to use a comparison operator.
Once you figure out the relation, you can express it with an
ifstatement.
ممتاز! أحد الحلول هو:
players = ['Charlie', 'Alice', 'Dylan', 'Bob'] for i in range(len(players)): for j in range(len(players)): if i < j: print(f'{players[i]} vs {players[j]}')