2.7. القوائم

القائمة هي تسلسل مرتّب وقابل للتغيير من القيم. وعلى خلاف السلاسل النصية والبايتات، يمكن للقوائم أن تحمل قيمًا من أي نوع، ويمكنك تغيير العناصر أو إضافتها أو إزالتها في مكانها.

2.7.1. إنشاء القوائم

تنشئ الأقواس المربعة قائمة حرفية:

empty   = []
nums    = [1, 2, 3]
mixed   = [1, "two", 3.0, True, None]    # any types
nested  = [[1, 2], [3, 4], [5, 6]]       # lists of lists

منشئ list يبني قائمة من أي كائن قابل للتكرار:

>>> list("abc")
['a', 'b', 'c']
>>> list(range(5))
[0, 1, 2, 3, 4]

2.7.2. الطول والفهرسة والتقطيع

len() يُعيد عدد العناصر. وتعمل الفهرسة والتقطيع بالطريقة نفسها كما في السلاسل النصية -- تبدأ المواضع من 0، وتُحسب الفهارس السالبة من النهاية، والشريحة الخارجة عن النطاق الصالح تُقتطع بصمت بدلًا من إثارة خطأ:

>>> nums = [10, 20, 30, 40, 50]
>>> len(nums)
5
>>> nums[0]
10
>>> nums[-1]
50
>>> nums[1:4]
[20, 30, 40]
A list of six cells, with positive indices 0..5 above and negative indices -6..-1 below each cell.

الفهارس الموجبة تُحسب من البداية؛ والفهارس السالبة تُحسب من النهاية.

صيغة التقطيع هي اختصار لكائن slice يبنيه Python خلف الكواليس. فـ nums[1:4] يساوي nums[slice(1, 4)]. ونادرًا ما تنشئ واحدًا يدويًا، لكن slice() مفيد أحيانًا لتخزين شريحة كقيمة لإعادة استخدامها:

head = slice(0, 3)
print(nums[head])             # [10, 20, 30]
print(letters[head])          # first three letters, same slice

2.7.3. تغيير القائمة

تدعم القوائم الإسناد المفهرس والمقطّع في مكانه:

>>> nums = [10, 20, 30]
>>> nums[0] = 99
>>> nums
[99, 20, 30]
>>> nums[1:3] = [200, 300, 400]    # slice can change the length
>>> nums
[99, 200, 300, 400]

أكثر دوال القائمة شيوعًا:

  • list.append() -- يضيف عنصرًا واحدًا إلى النهاية.

  • list.extend() -- يلحق كل عنصر من كائن قابل للتكرار.

  • list.insert() -- يُدرج في موضع معطى.

  • list.remove() -- يحذف أول ظهور لقيمة.

  • list.pop() -- يزيل عنصرًا ويُعيده (الأخير افتراضيًا).

  • list.clear() -- يزيل كل عنصر.

  • list.sort() -- يفرز في مكانه. مرّر reverse=True للترتيب التنازلي.

  • list.reverse() -- يعكس في مكانه.

>>> nums = []
>>> nums.append(1)
>>> nums.extend([2, 3])
>>> nums.insert(0, 99)
>>> nums
[99, 1, 2, 3]
>>> nums.pop()
3
>>> nums.sort()
>>> nums
[1, 2, 99]

هذه الدوال تعدّل القائمة في مكانها وتُعيد None. وكتابة

nums = nums.sort()    # nums is now None -- common bug

تكاد لا تكون أبدًا ما تريده؛ فقد تم فرز nums الأصلية، لكن الإسناد بعد ذلك يستبدل الاسم بالقيمة المُعادة. فإما أن تستدعي nums.sort() في سطر مستقل، أو أن تستخدم الدالة المدمجة sorted() للحصول على قائمة مفروزة جديدة دون تغيير الأصل.

2.7.4. العوامل

  • + يربط قائمتين في قائمة جديدة.

  • * يكرر قائمة.

  • in يختبر العضوية.

>>> [1, 2] + [3, 4]
[1, 2, 3, 4]
>>> [0] * 5
[0, 0, 0, 0, 0]
>>> 3 in [1, 2, 3]
True

2.7.5. التكرار على قائمة

حلقة for تمر على العناصر بالترتيب:

for n in [10, 20, 30]:
    print(n)

2.7.6. الأسماء البديلة والتغيير

القائمة قيمة واحدة في الذاكرة؛ ويمكن لعدة أسماء أن تشير إلى القائمة نفسها. والتغيير عبر اسم واحد يكون مرئيًا عبر كل اسم آخر يشير إلى القائمة نفسها.

Two variables a and b both pointing at the same list object; appending to a is visible through b.

a و b كلاهما يشير إلى القائمة نفسها. والتغيير عبر أي من الاسمين يغيّر ما تراه كل الأسماء الأخرى.

>>> a = [1, 2, 3]
>>> b = a
>>> a.append(4)
>>> b
[1, 2, 3, 4]                # same object, change is visible

لعمل نسخة مستقلة، قطّع القائمة بالكامل أو استدعِ منشئ list:

>>> c = a[:]                # or list(a)
>>> a.append(5)
>>> c
[1, 2, 3, 4]                # c is unaffected

هذا ينسخ فقط القائمة ذات المستوى الأعلى؛ أما القوائم المتداخلة فتظل مشتركة بين الأصل والنسخة.