مقدمة في علوم الحاسوب والبرمجة باستخدام Python › المحاضرة 11: الأسماء المستعارة (Aliasing) والاستنساخ (Cloning) 13 / 30 السابق التالي

المحاضرة 11: الأسماء المستعارة (Aliasing) والاستنساخ (Cloning)

المحاضرة 11: الأسماء المستعارة (Aliasing) والاستنساخ (Cloning)

المصادر والنسبة والترخيص

المادة الأصلية: آنا بيل (Ana Bell)، MIT OpenCourseWare (MIT OCW)، معهد ماساتشوستس للتكنولوجيا، مقرر 6.100L: مقدمة في علوم الحاسوب والبرمجة باستخدام Python، خريف 2022 (Fall 2022).

هذه ترجمة وتكييف عربي غير رسمي وفق رخصة CC BY-NC-SA 4.0: النسبة–غير التجاري–المشاركة بالمثل، ولا تعني اعتمادًا أو تأييدًا من MIT أو MIT OCW. شروط الاستخدام والاستشهاد.

منهج الترجمة: لكل صفحة في ملف الشرائح عنوان مستقل ورقم مطابق. شرائح التتبّع (التي تتكرّر فيها الشيفرة نفسها مع رسم بياني متغيّر) نُقلت كلّها مع جدول القيم. شرائح «تمارين التتبّع في المنزل» (At Home Tracing Examples) في الأصل قائمة على لقطات شاشة من Python Tutor، وقد نُقل نصّها وحده؛ ولم يُخمَّن محتوى اللقطات. النصّ المستخرَج من ملف PDF يحتوي في الشرائح 33 و35 و37 و39 على عبارة 6.0001 LECTURE 5 متبقّية من عرض قديم أعاد MIT استعماله؛ وقد أُشير إليها في موضعها ولم يُنسب المحتوى إلى مقرر آخر.

الشريحة 1: الأسماء المستعارة والاستنساخ (Aliasing, Cloning)

نزّل الشرائح وملفات .py لمتابعة الشرح.

6.100L، المحاضرة 11 — آنا بيل (Ana Bell).

الشريحة 2: إنشاء نسخة من القائمة (Making a Copy of the List)

  • يمكنك إنشاء نسخة من كائن قائمة بمضاعفة كل عناصره (على المستوى الأعلى — Top Level) في كائن قائمة جديد.
  • Lcopy = L[:]
  • هذا يكافئ المرور على L وإلحاق كل عنصر في Lcopy.
  • هذا لا ينشئ نسخة من العناصر التي هي قوائم (سنرى كيف نفعل ذلك في نهاية المحاضرة).
Loriginal = [4,5,6]
Lnew = Loriginal[:]
الاسم القيمة
Loriginal [4,5,6]
Lnew [4,5,6]

الشريحة 3: جرّب بنفسك! (YOU TRY IT!)

اكتب دالة تحقّق هذه المواصفات.

تلميح: اصنع نسخةً لحفظ العناصر، ثم استعمل L.clear() لإفراغ القائمة وإعادة ملئها بالعناصر التي تقرّر الاحتفاظ بها.

def remove_all(L, e):
    """
    L is a list
    Mutates L to remove all elements in L that are equal to e
    Returns None
    """
L = [1,2,2,2]

remove_all(L, 2)
print(L)

# prints [1]

الشريحة 4: العمليات على القوائم — الإزالة (remove)

  • احذف عنصرًا عند فهرس محدّد بـ del(L[index]).
  • أزل عنصرًا من نهاية القائمة بـ L.pop()، وتُرجِع العنصر المُزال (ويمكن استدعاؤها بفهرس محدّد: L.pop(3)).
  • أزل عنصرًا محدّدًا بـ L.remove(element):
    • تبحث عن العنصر وتزيله (فهي تُغيّر القائمة).
    • إذا تكرّر العنصر أكثر من مرة، تُزيل أول تكرار.
    • إذا لم يكن العنصر في القائمة، تعطي خطأ.

نفّذ الأسطر التالية بالترتيب:

L = [2,1,3,6,3,7,0] # do below in order
L.remove(2)   # mutates L = [1,3,6,3,7,0]
L.remove(3)   # mutates L = [1,6,3,7,0]
del(L[1])     # mutates L = [1,3,7,0]
a = L.pop()   # returns 0 and mutates L = [1,3,7]

الشريحة 5: تمرين باستخدام remove بدل النسخ والإفراغ (Exercise with Remove instead of Copy and Clear)

  • أعد كتابة الشيفرة لتزيل e طالما كان لا يزال في القائمة.
  • تعمل جيدًا!
def remove_all(L, e):
    """
    L is a list
    Mutates L to remove all elements in L that are equal to e
    Returns None.
    """
while e in L:
    L.remove(e)

الشريحة 6: تمرين باستخدام remove — ماذا لو كانت الشيفرة كالتالي؟

def remove_all(L, e):
    """
    L is a list
    Mutates L to remove all elements in L that are equal to e
    Returns None.
    """
for elem in L:
    if elem == e:
        L.remove(e)

L = [1,2,2,2]
remove_all(L, 2)
print(L)
# should print [1]

الشريحة 7: تمرين باستخدام remove — إضافة اسم elem

الشريحة نفسها، والمخطط يُظهر اسم elem مربوطًا بالقيمة 2 (وهي أول قيمة في L):

الاسم القيمة
L [1,2,2,2]
elem 2

الشريحة 8: تمرين باستخدام remove — الخطوة التالية

الشريحة نفسها، والقيم بعد أول تكرار:

الاسم القيمة
L [1,2,2]
elem 2

ملاحظة المترجم: الشرائح 7 إلى 10 تعرض القيم على جانبي السطر في المستخرَج؛ نُقلت الجداول أعلاه موحّدة، والقيم نفسها هي ما تظهر في الأصل.

الشريحة 9: تمرين باستخدام remove — الخطوة التالية

الاسم القيمة
L [1,2]
elem 2

الشريحة 10: تمرين باستخدام remove — الخطوة التالية

الاسم القيمة
L [1,2]

ملاحظة المترجم: في المستخرَج لقيم L المتكرّرة ([1,2,2,2] ثم [1,2,2] ثم [1,2]) تظهر موزّعة على الشرائح 7 إلى 11 بحسب موضع كل رسم بياني.

الشريحة 11: تمرين باستخدام remove — النتيجة

  • ليس صحيحًا! لقد أزلنا عناصر أثناء ما كنّا نمرّ على القائمة!
الاسم القيمة
L [1,2]

المتوقّع [1]، والمطبوع [1,2].

الشريحة 12: لمحة عامة عن الأمثلة الصعبة (Tricky Examples Overview)

  • المثال الصعب 1: حلقة تمرّ على فهارس L وتُغيّر L في كل مرة (تضيف عناصر أكثر).
  • المثال الصعب 2: حلقة تمرّ على عناصر L مباشرة وتُغيّر L في كل مرة (تضيف عناصر أكثر).
  • المثال الصعب 3: حلقة تمرّ على عناصر L مباشرة لكنها تُعيد إسناد L إلى كائن جديد في كل مرة.
  • المثال الصعب 4: حلقة تمرّ على عناصر L مباشرة وتُغيّر L بإزالة عناصر.

الشريحة 13: المثال الصعب 4

  • رابط Python Tutor لمشاهدة التنفيذ خطوة بخطوة: https://www.pythontutor.com/
  • نريد تغيير L1 لإزالة أي عناصر موجودة أيضًا في L2.
def remove_dups(L1, L2):
    for e in L1:
        if e in L2:
            L1.remove(e)

L1 = [10, 20, 30, 40]
L2 = [10, 20, 50, 60]
remove_dups(L1, L2)
  • L1 هي [20,30,40] لا [30,40]. لماذا؟
    • أنت تُغيّر قائمة وأنت تمرّ عليها.
    • بايثون تستعمل عدّادًا داخليًّا يتتبّع الفهرس في الحلقة على القائمة L1.
    • التغيير يُغيّر القائمة لكن بايثون لا تُحدّث العدّاد.
    • الحلقة لا ترى العنصر 20 أبدًا.

الشريحة 14: التغيير والتكرار بدون نسخة (Mutation and Iteration without Clone)

def remove_dups(L1, L2):
    for e in L1:
        if e in L2:
            L1.remove(e)

L1 = [10, 20, 30, 40]
L2 = [10, 20, 50, 60]
remove_dups(L1, L2)

القيم قبل التنفيذ:

الاسم القيمة
L1 [10,20,30,40]
L2 [10,20,50,60]
e —

الشريحة 15: التغيير والتكرار بدون نسخة — بعد التنفيذ

نفس الشيفرة، والقيم بعد التنفيذ:

الاسم القيمة
L1 [20,30,40]
L2 [10,20,50,60]
e 40

الشريحة 16: التغيير والتكرار بدون نسخة — القيم نفسها

نفس الشيفرة، ونفس القيم:

الاسم القيمة
L1 [20,30,40]
L2 [10,20,50,60]
e 40

الشريحة 17: التغيير والتكرار بدون نسخة — القيم نفسها

نفس الشيفرة، ونفس القيم:

الاسم القيمة
L1 [20,30,40]
L2 [10,20,50,60]
e 40

الشريحة 18: التغيير والتكرار مع نسخة (Mutation and Iteration with Clone)

  • اصنع نسخة (Clone) بـ [:].
النسخة الصحيحة النسخة الخاطئة
def remove_dups(L1, L2): def remove_dups(L1, L2):
L1_copy = L1[:] for e in L1:
for e in L1_copy: if e in L2:
if e in L2: L1.remove(e)
L1.remove(e)
  • النسخة الجديدة تعمل!
    • مرّ على نسخة.
    • غيّر القائمة الأصلية، لا النسخة.
    • الفهرسة صارت متّسقة.

الشريحة 19: التغيير والتكرار مع نسخة — قبل التنفيذ

def remove_dups(L1, L2):
    L1_copy = L1[:]
    for e in L1_copy:
        if e in L2:
            L1.remove(e)

L1 = [10, 20, 30, 40]
L2 = [10, 20, 50, 60]
remove_dups(L1, L2)
الاسم القيمة
L1_copy [10,20,30,40]
L1 [10,20,30,40]
L2 [10,20,50,60]
e —

الشريحة 20: التغيير والتكرار مع نسخة — الخطوة الأولى

الاسم القيمة
L1_copy [10,20,30,40]
L1 [20,30,40]
L2 [10,20,50,60]
e 10

الشريحة 21: التغيير والتكرار مع نسخة — الخطوة نفسها

الاسم القيمة
L1_copy [10,20,30,40]
L1 [20,30,40]
L2 [10,20,50,60]
e 20

الشريحة 22: التغيير والتكرار مع نسخة — الخطوة الثانية

الاسم القيمة
L1_copy [10,20,30,40]
L1 [30,40]
L2 [10,20,50,60]
e 30

الشريحة 23: التغيير والتكرار مع نسخة — الخطوة نفسها

الاسم القيمة
L1_copy [10,20,30,40]
L1 [30,40]
L2 [10,20,50,60]
e 40

الشريحة 24: التغيير والتكرار مع نسخة — بعد الانتهاء

الاسم القيمة
L1_copy [10,20,30,40]
L1 [30,40]
L2 [10,20,50,60]

الشريحة 25: الأسماء المستعارة (Aliasing)

  • قد تكون المدينة معروفة بأسماء كثيرة (Many Names).
  • صفات مدينة: صغيرة (Small)، متقنة التقنية (Tech-Savvy).
  • كل الألقاب تشير إلى المدينة نفسها.
الاسم الصفات قبل الصفات بعد
Boston small وtech-savvy small وtech-savvy وsnowy
The Hub small وtech-savvy small وtech-savvy وsnowy
Beantown small وtech-savvy small وtech-savvy وsnowy
Athens of America small وtech-savvy small وtech-savvy وsnowy
  • أضف صفة جديدة إلى لقب واحد… ثمفكل الأسماء المستعارة تشير جميعًا إلى الصفة الجديدة.

الشريحة 26: التغيير والتكرار مع اسم مستعار (Mutation and Iteration with Alias)

L1_copy = L1

  • علامة الإسناد = على كائن قابل للتغيير تنشئ اسمًا مستعارًا (Alias)، لا نسخة (Clone).
النسخة بالاسم المستعار النسخة الصحيحة
def remove_dups(L1, L2): def remove_dups(L1, L2):
L1_copy = L1 L1_copy = L1[:]
for e in L1_copy: for e in L1_copy:
if e in L2: if e in L2:
L1.remove(e) L1.remove(e)
  • استعمال إسناد بسيط دون إنشاء نسخة:
    • ينشئ اسمًا مستعارًا للقائمة (الكائن نفسه مُشارًا إليه باسم آخر).
    • هذا مثل المرور على L نفسها، فهو لا يعمل!

الشريحة 27: التغيير والتكرار مع اسم مستعار — القيم

def remove_dups(L1, L2):
    L1_copy = L1
    for e in L1_copy:
        if e in L2:
            L1.remove(e)

L1 = [10, 20, 30, 40]
L2 = [10, 20, 50, 60]
remove_dups(L1, L2)
الاسم القيمة
L1_copy 10,20,30,40
L1 [20,30,40]
L2 [10,20,50,60]
e 40

ملاحظة المترجم: L1_copy وL1 اسمان لكائن واحد، ولذلك لا تظهر لقيمة L1_copy قوسان مربّعان منفصلة في الأصل.

الشريحة 28: الفكرة الكبرى (BIG IDEA)

عندما تمرّر قائمة كمعامل (Parameter) إلى دالة، فأنت تصنع اسمًا مستعارًا. المعامل الفعلي (Actual Parameter، من استدعاء الدالة) هو اسم مستعار للمعامل الصوري (Formal Parameter، من تعريف الدالة).

الشريحة 29: الأسماء المستعارة — في نداء الدالة

def remove_dups(L1, L2):
    L1_copy = L1
    for e in L1_copy:
        if e in L2:
            L1.remove(e)

La = [10, 20, 30, 40]
Lb = [10, 20, 50, 60]
remove_dups(La, Lb)
print(La)
الاسم في النطاق العام الاسم في نطاق الدالة القيمة
La L1 [20,30,40]
Lb L2 [10,20,50,60]
— L1_copy [10,20,30,40]
— e 40

الشريحة 30: الأسماء المستعارة والنسخ السطحية والنسخ العميقة مع عناصر قابلة للتغيير (Aliases, Shallow Copies, and Deep Copies with Mutable Elements)

شريحة عنوان تعلن موضوعًا جديدًا.

الشريحة 31: التحكّم في النسخ (Control Copying)

  • الإسناد (Assignment) ينشئ فقط مؤشّرًا جديدًا (New Pointer) إلى الكائن نفسه.
old_list = [[1,2],[3,4],[5,'foo']]
new_list = old_list
new_list[2][1] = 6

print("New list:", new_list)  # New list: [[1,2],[3,4],[5,6]]
print("Old list:", old_list)  # Old list: [[1,2],[3,4],[5,6]]
  • فالتغيير في كائن واحد يغيّر الآخر.
  • الرسم البياني: كلا الاسمين old_list وnew_list يشيران إلى الكائن نفسه، وفيه [1,2] و[3,4] و[5,6] بعد التغيير.

الشريحة 32: التحكّم في النسخ — النسخ السطحي (Shallow Copying)

  • لنفترض أننا نريد إنشاء نسخة من قائمة، لا مجرّد مؤشّر مشترك.
  • النسخ السطحي (Shallow Copying) يفعل هذا على المستوى الأعلى من القائمة.
  • وهو مكافئ للصيغة [:].
  • أي عناصر قابلة للتغيير لا تُنسخ.
  • استعمل هذا عندما تحتوي قائمتك على كائنات غير قابلة للتغيير فقط.
import copy

old_list = [[1,2],[3,4],[5,6]]
new_list = copy.copy(old_list)
print("New list:", new_list)
print("Old list:", old_list)

ملاحظة المترجم: الشريحة تحمل في أصلها عبارة 6.0001 LECTURE 5 متبقّية من عرض قديم في الملف؛ وهي ليست إشارة إلى مقرر آخر، بل أثر باقٍ في ملف MIT نفسه، وقد أُشير إليها هنا للشفافية.

الشريحة 33: التحكّم في النسخ — شيفرة النسخ السطحي

old_list = [[1,2],[3,4],[5,6]]
new_list = copy.copy(old_list)
print("New list:", new_list)  # New list: [[1,2],[3,4],[5,6]]
print("Old list:", old_list)  # Old list: [[1,2],[3,4],[5,6]]

الرسم البياني: old_list وnew_list كائنان مختلفان في المستوى الأعلى، وفي كلٍّ منهما القوائم الفرعية نفسها [1,2] و[3,4] و[5,6] مشتركة.

ملاحظة المترجم: في هذه الشريحة أيضًا تتبقّى في الملف الأصلي عبارة 6.0001 LECTURE 5 من عرض قديم.

الشريحة 34: التحكّم في النسخ — تغيير البنية الأعلى

  • الآن نغيّر البنية في المستوى الأعلى.
import copy

old_list = [[1,2],[3,4],[5,6]]
new_list = copy.copy(old_list)
old_list.append([7,8])

print("New list:", new_list)
print("Old list:", old_list)

الشريحة 35: التحكّم في النسخ — النتيجة

old_list = [[1,2],[3,4],[5,6]]
new_list = copy.copy(old_list)
old_list.append([7,8])

print("New list:", new_list)  # New list: [[1,2],[3,4],[5,6]]
print("Old list:", old_list)  # Old list: [[1,2],[3,4],[5,6],[7,8]]

الرسم البياني: old_list صار [1,2] و[3,4] و[5,6] و[7,8]، بينما new_list بقي [1,2] و[3,4] و[5,6].

ملاحظة المترجم: في هذه الشريحة أيضًا تتبقّى في الملف الأصلي عبارة 6.0001 LECTURE 5 من عرض قديم.

الشريحة 36: التحكّم في النسخ — تغيير عنصر في بنية فرعية

  • لكن إذا غيّرنا عنصرًا في إحدى البنى الفرعية، فهما مشتركة (Shared)!
  • إذا لم تكن عناصرك قابلة للتغيير فليست هذه مشكلة.
import copy

old_list = [[1,2],[3,4],[5,6]]
new_list = copy.copy(old_list)
old_list.append([7,8])
old_list[1][1] = 9

print("New list:", new_list)
print("Old list:", old_list)

الشريحة 37: التحكّم في النسخ — النتيجة

old_list = [[1,2],[3,4],[5,6]]
new_list = copy.copy(old_list)
old_list.append([7,8])
old_list[1][1] = 9

print("New list:", new_list)  # New list: [[1,2],[3,9],[5,6]]
print("Old list:", old_list)  # Old list: [[1,2],[3,9],[5,6],[7,8]]

الرسم البياني: البنية الفرعية [3,4] صارت [3,9] في الكائنين معًا، لأنها مشتركة.

ملاحظة المترجم: في هذه الشريحة أيضًا تتبقّى في الملف الأصلي عبارة 6.0001 LECTURE 5 من عرض قديم.

الشريحة 38: التحكّم في النسخ — النسخة العميقة (Deep Copy)

  • إذا أردنا أن تكون كل البنى نسخًا جديدة، نحتاج إلى نسخة عميقة (Deep Copy).
  • استعمل النسخة العميقة عندما قد تحتوي قائمتك على عناصر قابلة للتغيير، لضمان نسخ كل بنية في كل مستوى.
import copy

old_list = [[1,2],[3,4],[5,6]]

new_list = copy.deepcopy(old_list)
old_list.append([7,8])
old_list[1][1] = 9

print("New list:", new_list)
print("Old list:", old_list)

الشريحة 39: التحكّم في النسخ — نتيجة النسخة العميقة

old_list = [[1,2],[3,4],[5,6]]

new_list = copy.deepcopy(old_list)
old_list.append([7,8])
old_list[1][1] = 9

print("New list:", new_list)  # New list: [[1,2],[3,4],[5,6]]
print("Old list:", old_list)  # Old list: [[1,2],[3,9],[5,6],[7,8]]

الرسم البياني: في old_list البنية الفرعية [3,9]، وفي new_list البنية الفرعية [3,4] — أي نسختان مستقلّتان تمامًا.

ملاحظة المترجم: في هذه الشريحة أيضًا تتبقّى في الملف الأصلي عبارة 6.0001 LECTURE 5 من عرض قديم.

الشريحة 40: القوائم في الذاكرة (Lists in Memory)

  • افصل بين فكرة الكائن (Object) والاسم الذي نمنحه لهذا الكائن.
    • القائمة كائن في الذاكرة.
    • اسم المتغيّر يشير إلى الكائن.
  • القوائم قابلة للتغيير وتتصرّف بشكل مختلف عن الأنواع غير القابلة للتغيير.
  • استعمال علامة المساواة بين كائنات قابلة للتغيير ينشئ أسماء مستعارة (Aliases).
    • المتغيّران يشيران إلى الكائن نفسه في الذاكرة.
    • أي متغيّر يشير إلى ذلك الكائن يتأثّر بتغيير الكائن، حتى لو كان التغيير بالإشارة إلى اسم آخر.
  • إذا أردت نسخة، فأنت تطلب من بايثون صراحةً أن يصنع نسخة.
  • العبارة المفتاحية التي ينبغي أن تحفظها عند العمل مع القوائم هي الآثار الجانبية (Side Effects)، وبخاصة عند التعامل مع الأسماء المستعارة — اسمان يشيران إلى البنية نفسها في الذاكرة.
  • Python Tutor هو أعزّ صديق يساعدك على ترتيب هذا الأمر: http://www.pythontutor.com/

الشريحة 41: لماذا القوائم والصفوف؟ (Why Lists and Tuples?)

  • إذا كان التغيير (Mutation) يسبب كل هذه المشاكل، فلماذا نريد القوائم أصلًا؟ أليست الصفوف تكفي؟
    • الكفاءة (Efficiency): إذا كنّا نجرّسل تسلسلات كبيرة جدًا، فلا نريد نسخَها كاملة في كل مرة نغيّر فيها عنصرًا.
  • إذا كانت القوائم تفعل كل ما تفعله الصفوف تقريبًا، فلماذا نريد القوائم أصلًا؟
    • البنى غير القابلة للتغيير (Immutable Structures) قد تكون ذات قيمة كبيرة في سياق أنواع الكائنات الأخرى.
    • لا نريد أن تغيّر شيفرة أخرى بالخطأ بيانات مهمة؛ الصفوف تحمي من ذلك.
    • وقد تكون أسرع قليلًا.

الشريحة 42: تمارين تتبّع في المنزل (At Home Tracing Examples)

أمثلة تتبّع في المنزل تعرض الأسماء المستعارة (Aliasing) والاستنساخ (Cloning).

ملاحظة المترجم: نصّ هذه الشريحة فقير، وقد اعتمد في الأصل على لقطات شاشة من Python Tutor والرسوم البيانية المميّزة. لم تُضمَّن اللقطات هنا لأن ترخيصها غير واضح داخل مادة OCW، ولم يُخمَّن محتواها.

الشريحة 43: الأسماء المستعارة (Aliases)

  • hot اسم مستعار لـwarm — تغيير أحدهما يغيّر الآخر!
  • الدالة append() لها أثر جانبي.

ملاحظة المترجم: بقية الشريحة لقطات شاشة من Python Tutor لا يمكن نقلها بترخيص واضح، ولذلك لم تُنقل.

الشريحة 44: الأسماء المستعارة (Aliases)

  • hot اسم مستعار لـwarm — تغيير أحدهما يغيّر الآخر!
  • الدالة append() لها أثر جانبي.

ملاحظة المترجم: بقية الشريحة لقطات شاشة من Python Tutor لا يمكن نقلها بترخيص واضح، ولذلك لم تُنقل.

الشريحة 45: استنساخ قائمة (Cloning a List)

  • أنشئ قائمة جديدة وانسخ كل عنصر فيها باستخدام نسخة (Clone).
chill = cool[:]

ملاحظة المترجم: بقية الشريحة لقطات شاشة من Python Tutor لا يمكن نقلها بترخيص واضح، ولذلك لم تُنقل.

الشريحة 46: استنساخ قائمة (Cloning a List)

  • أنشئ قائمة جديدة وانسخ كل عنصر فيها باستخدام نسخة (Clone).
chill = cool[:]

ملاحظة المترجم: بقية الشريحة لقطات شاشة من Python Tutor لا يمكن نقلها بترخيص واضح، ولذلك لم تُنقل.

الشريحة 47: استنساخ قائمة (Cloning a List)

  • أنشئ قائمة جديدة وانسخ كل عنصر فيها باستخدام نسخة (Clone).
chill = cool[:]

ملاحظة المترجم: بقية الشريحة لقطات شاشة من Python Tutor لا يمكن نقلها بترخيص واضح، ولذلك لم تُنقل.

الشريحة 48: قوائم من قوائم من قوائم… (Lists of Lists of Lists of…)

  • يمكن أن تكون القوائم متداخلة (Nested Lists).
  • الآثار الجانبية (Side Effects) ما زالت ممكنة بعد التغيير.

ملاحظة المترجم: بقية الشريحة لقطات شاشة من Python Tutor لا يمكن نقلها بترخيص واضح، ولذلك لم تُنقل.

الشريحة 49: قوائم من قوائم من قوائم… (Lists of Lists of Lists of…)

  • يمكن أن تكون القوائم متداخلة (Nested Lists).
  • الآثار الجانبية (Side Effects) ما زالت ممكنة بعد التغيير.

ملاحظة المترجم: بقية الشريحة لقطات شاشة من Python Tutor لا يمكن نقلها بترخيص واضح، ولذلك لم تُنقل.

الشريحة 50: قوائم من قوائم من قوائم… (Lists of Lists of Lists of…)

  • يمكن أن تكون القوائم متداخلة (Nested Lists).
  • الآثار الجانبية (Side Effects) ما زالت ممكنة بعد التغيير.

ملاحظة المترجم: بقية الشريحة لقطات شاشة من Python Tutor لا يمكن نقلها بترخيص واضح، ولذلك لم تُنقل.

الشريحة 51: قوائم من قوائم من قوائم… (Lists of Lists of Lists of…)

  • يمكن أن تكون القوائم متداخلة (Nested Lists).
  • الآثار الجانبية (Side Effects) ما زالت ممكنة بعد التغيير.

ملاحظة المترجم: بقية الشريحة لقطات شاشة من Python Tutor لا يمكن نقلها بترخيص واضح، ولذلك لم تُنقل.

الشريحة 52: قوائم من قوائم من قوائم… (Lists of Lists of Lists of…)

  • يمكن أن تكون القوائم متداخلة (Nested Lists).
  • الآثار الجانبية (Side Effects) ما زالت ممكنة بعد التغيير.

ملاحظة المترجم: بقية الشريحة لقطات شاشة من Python Tutor لا يمكن نقلها بترخيص واضح، ولذلك لم تُنقل.

الشريحة 53: قوائم من قوائم من قوائم… (Lists of Lists of Lists of…)

  • يمكن أن تكون القوائم متداخلة (Nested Lists).
  • الآثار الجانبية (Side Effects) ما زالت ممكنة بعد التغيير.

ملاحظة المترجم: بقية الشريحة لقطات شاشة من Python Tutor لا يمكن نقلها بترخيص واضح، ولذلك لم تُنقل.

الشريحة 54: MITOpenCourseWare

https://ocw.mit.edu

مقرر 6.100L: مقدمة في علوم الحاسوب والبرمجة باستخدام Python، خريف 2022.

للاطّلاع على كيفية الاستشهاد بهذه المواد أو على شروط الاستخدام: https://ocw.mit.edu/terms.