قوائم بايثون

تحتوي لغة بايثون على نوع قائمة مضمّن رائع يُسمى list. يتم كتابة القيم الحرفية للقوائم بين قوسَين مربّعَين [ ]. تعمل القوائم بشكل مشابه للسلاسل، فيمكنك استخدام الدالة len() والقوسَين المربّعَين [ ] للوصول إلى البيانات، مع وضع العنصر الأول في الفهرس 0. (اطّلِع على مستندات قائمة python.org الرسمية).

  colors = ['red', 'blue', 'green']
  print(colors[0])    ## red
  print(colors[2])    ## green
  print(len(colors))  ## 3

قائمة السلاسل 'أحمر' 'أزرق' 'أخضر'

لا يؤدي الربط باستخدام = في القوائم إلى إنشاء نسخة. بدلاً من ذلك، تؤدي عملية الربط إلى توجيه المتغيّرين إلى القائمة الواحدة في الذاكرة.

  b = colors   ## Does not copy the list

كل من اللونين و b يشيران إلى القائمة الواحدة

"القائمة الفارغة" هي مجرد زوج فارغ من الأقواس [ ]. يعمل الرمز "+" على إلحاق قائمتَين، لذا فإنّ [1, 2] + [3, 4] ينتج عنه [1, 2, 3, 4] (هذا يشبه تمامًا + مع السلاسل).

من أجل وإلى داخل

إنّ بنية *for* و*in* في Python مفيدة للغاية، وسنرى أول استخدام لها مع القوائم. إنّ صيغة *for* -- for var in list -- هي طريقة سهلة للاطّلاع على كل عنصر في القائمة (أو في مجموعة أخرى). لا تُضِف أي عناصر إلى القائمة أو تُزيل أي عناصر منها أثناء التكرار.

  squares = [1, 4, 9, 16]
  sum = 0
  for num in squares:
    sum += num
  print(sum)  ## 30

إذا كنت تعرف نوع العناصر في القائمة، استخدِم اسم متغيّر في الحلقة لتسجيل هذه المعلومات، مثل "num" أو "name" أو "url". بما أنّ رمز Python لا يحتوي على بنية نحوية أخرى لتذكيرك بالأنواع، فإنّ أسماء المتغيّرات هي طريقة رئيسية لمواكبة ما يحدث. (هذا مضلِّل بعض الشيء. مع ازدياد نسبة ظهور لغة بايثون، ستظهر لك مراجع لتلميحات الكتابة تسمح لك بإضافة معلومات الكتابة إلى تعريفات الدوال. لا تستخدم Python هذه التلميحات المتعلّقة بالأنواع عند تنفيذ برامجك. وتستخدمها برامج أخرى، مثل بيئات التطوير المتكاملة (IDE) وأدوات التحليل الثابت، مثل أدوات فحص الأخطاء أو أدوات التحقّق من النوع، للتحقّق مما إذا كان يتم استدعاء دوالّك باستخدام وسيطات متوافقة.)

إنّ البنية *in* بحد ذاتها هي طريقة سهلة لاختبار ما إذا كان العنصر يظهر في قائمة (أو مجموعة أخرى). يُجري العنصر value in collection اختبارًا لمعرفة ما إذا كانت القيمة موجودة في المجموعة، ويعرض القيمة "صحيح" أو "خطأ".

  list = ['larry', 'curly', 'moe']
  if 'curly' in list:
    print('yay') ## yay

يتم استخدام بنية for/in بشكل شائع جدًا في رمز بايثون وتعمل على أنواع بيانات أخرى غير القائمة، لذا عليك حفظ بنيتها فقط. قد تكون لديك عادات من لغات أخرى تبدأ فيها بالتكرار يدويًا في مجموعة، ولكن في بايثون عليك استخدام for/in فقط.

يمكنك أيضًا استخدام for/in للعمل على سلسلة. تعمل السلسلة كقائمة بأحرفها، لذا تطبع for ch in s: print(ch) جميع الأحرف في سلسلة.

النطاق

تعرِض دالة range(n) الأرقام 0 و1 و... n-1، وتعرِض دالة range(a, b) الأرقام a وa+1 و... b-1 حتى الرقم الأخير بدون تضمينه. يتيح لك الجمع بين for-loop ودالة range() إنشاء حلقة رقمية تقليدية للتكرار الحلقي for:

  ## print the numbers from 0 through 99
  for i in range(100):
    print(i)

هناك نوع مختلف من دالة xrange() يتجنّب تكلفة إنشاء القائمة بأكملها في الحالات الحسّاسة للأداء (في Python 3، ستتضمّن دالة range() أداءً جيدًا ويمكنك تجاهل دالة xrange()).

أثناء التكرار الحلقي

تتضمّن Python أيضًا حلقة while العادية، وتعمل عبارات *break* و*continue* كما في C++ وJava، ما يؤدي إلى تغيير مسار الحلقة الداخلية. تحلّ حلقتا for/in أعلاه المشكلة الشائعة المتمثّلة في تكرار كل عنصر في قائمة، ولكن تمنحك حلقة while إمكانية التحكّم الكامل في أرقام الفهرسة. إليك تكرار حلقي while الذي يصل إلى كل عنصر ثالث في القائمة:

  ## Access every 3rd element in a list
  i = 0
  while i < len(a):
    print(a[i])
    i = i + 3

طرق إدراج البيانات

في ما يلي بعض طرق القوائم الشائعة الأخرى.

  • list.append(elem) - لإضافة عنصر واحد إلى نهاية القائمة خطأ شائع: لا يعرض القائمة الجديدة، بل يُعدّل القائمة الأصلية فقط.
  • list.insert(index, elem) - لإدراج العنصر في الفهرس المحدّد، مع نقل العناصر إلى اليمين
  • تضيف list.extend(list2) العناصر في list2 إلى نهاية القائمة. يتشابه استخدام + أو += في قائمة مع استخدام extend().
  • list.index(elem) - للبحث عن العنصر المحدّد من بداية القائمة وعرض فهرسه تُعرِض خطأ ValueError في حال عدم ظهور العنصر (استخدِم "in" للتحقّق بدون خطأ ValueError).
  • list.remove(elem) - للبحث عن أول مثيل للعنصر المحدّد وإزالته (يتم طرح ValueError في حال عدم توفّره)
  • list.sort() - لترتيب القائمة في مكانها (لا يتم عرضها) (يُفضّل استخدام الدالة sorted() الموضّحة لاحقًا).
  • list.reverse()‎ - تُعيد ترتيب القائمة (لا تعرضها)
  • list.pop(index) - لإزالة العنصر في الفهرس المحدّد وإعادته تعرِض العنصر الأيمن إذا تم حذف الفهرس (يُعدّ ذلك عكس append() تقريبًا).

يُرجى العِلم أنّ هذه هي *الطرق* على عنصر قائمة، في حين أنّ len() هي دالة تأخذ القائمة (أو السلسلة أو أيّ شيء آخر) كوسيطة.

  list = ['larry', 'curly', 'moe']
  list.append('shemp')         ## append elem at end
  list.insert(0, 'xxx')        ## insert elem at index 0
  list.extend(['yyy', 'zzz'])  ## add list of elems at end
  print(list)  ## ['xxx', 'larry', 'curly', 'moe', 'shemp', 'yyy', 'zzz']
  print(list.index('curly'))    ## 2

  list.remove('curly')         ## search and remove that element
  list.pop(1)                  ## removes and returns 'larry'
  print(list)  ## ['xxx', 'moe', 'shemp', 'yyy', 'zzz']

خطأ شائع: تجدر الإشارة إلى أنّ الطرق المذكورة أعلاه لا *تُرجع* القائمة المعدَّلة، وإنما تعدِّل القائمة الأصلية فقط.

  list = [1, 2, 3]
  print(list.append(4))   ## NO, does not work, append() returns None
  ## Correct pattern:
  list.append(4)
  print(list)  ## [1, 2, 3, 4]

زيادة عدد العناصر في القائمة

أحد الأنماط الشائعة هو بدء قائمة على أنّها القائمة الفارغة []، ثم استخدام append() أو extend() لإضافة عناصر إليها:

  list = []          ## Start as the empty list
  list.append('a')   ## Use append() to add elements
  list.append('b')

إدراج الشرائح

تعمل الشرائح على القوائم تمامًا كما تعمل على السلاسل، ويمكن استخدامها أيضًا لتغيير الأجزاء الفرعية من القائمة.

  list = ['a', 'b', 'c', 'd']
  print(list[1:-1])   ## ['b', 'c']
  list[0:2] = 'z'    ## replace ['a', 'b'] with ['z']
  print(list)         ## ['z', 'c', 'd']

التمرين: list1.py

للتدرب على المواد الواردة في هذا القسم، جرّب المسائل في list1.py التي لا تستخدم التصنيف (في التمارين الأساسية).