القوائم list في بايثون

من موسوعة حسوب
مراجعة 09:12، 7 أكتوبر 2022 بواسطة جميل-بيلوني (نقاش | مساهمات)
(فرق) → مراجعة أقدم | المراجعة الحالية (فرق) | مراجعة أحدث ← (فرق)

تمتلك بايثون عددًا من أنواع البيانات المركبة والتي تستخدم لتجميع القيم الأخرى مع بعضها البعض، والقوائم هي أوسع هذه الأنواع وأكثرها شمولًا، ويمكن كتابتها كقائمة من القيم (العناصر) المفصولة عن بعضها البعض بفواصل (،) ومحاطة بأقواس مربعة. يمكن للقوائم أن تتضمّن أنواعًا مختلفة، ولكن عادة ما تكون العناصر كلها من النوع نفسه.

>>> squares = [1, 4, 9, 16, 25]
>>> squares
[1, 4, 9, 16, 25]
دورة علوم الحاسوب
  • 62 ساعة فيديو تدريبية
  • من الصفر دون الحاجة لخبرة مسبقة
  • شهادة معتمدة من أكاديمية حسوب
  • متابعة أثناء الدورة من فريق مختص

فهرسة القوائم واقتطاع أجزاء منها

كما هو الحال مع السلاسل النصية (والأنواع الأخرى من التسلسلات [sequence])، يمكن فهرسة القوائم واقتطاع أجزاء منها:

>>> squares[0]  # تعيد عملية الفهرسة العنصر المطلوب
1
>>> squares[-1]
25
>>> squares[-3:]  # تعيد عملية الاقتطاع قائمة جديدة
[9, 16, 25]

تعيد جميع عمليات الاقتطاع قائمة جديدة تتضمن العناصر المطلوبة، وهذا يعني أن عملية الاقتطاع التالية تعيد نسخة جديدة من القائمة:

>>> squares[:]
[1, 4, 9, 16, 25]

تدعم القوائم عمليات مثل الربط:

>>> squares + [36, 49, 64, 81, 100]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

ولكن على العكس من السلاسل النصية فإنّ القوائم قابلة للتعديل (mutable)، أي يمكن تعديل محتوياتها حسب  الحاجة:

>>> cubes = [1, 8, 27, 65, 125]  # هنالك خطأ ما
>>> 4 ** 3  # مكعب الرقم 4 يساوي 64 وليس 65
64
>>> cubes[3] = 64  # استبدل القيمة الخاطئة
>>> cubes
[1, 8, 27, 64, 125]

يمكن أيضًا إضافة عناصر جديدة إلى نهاية القائمة، وذلك بواسطة التابع append()‎:

>>> cubes.append(216)  # أضف مكعب الرقم 6
>>> cubes.append(7 ** 3)  # ومكعب الرقم 7
>>> cubes
[1, 8, 27, 64, 125, 216, 343]

يمكن الإسناد إلى الأجزاء المقتطعة من القائمة، ويمكن لهذه العملية أن تغير طول القائمة أو تحذف عناصرها بالكامل:

>>> letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
>>> letters
['a', 'b', 'c', 'd', 'e', 'f', 'g']
>>> # استبدال بعض القيم
>>> letters[2:5] = ['C', 'D', 'E']
>>> letters
['a', 'b', 'C', 'D', 'E', 'f', 'g']
>>> # ستحذف القيم الآن
>>> letters[2:5] = []
>>> letters
['a', 'b', 'f', 'g']
>>> # إفراغ القائمة وذلك بحذف جميع العناصر وتحويلها إلى قائمة فارغة
>>> letters[:] = []
>>> letters
[]

يمكن تنفيذ الدالة len() على القوائم أيضًا للحصول على عدد العناصر في القائمة:

>>> letters = ['a', 'b', 'c', 'd']
>>> len(letters)
4

يمكن إنشاء قوائم متداخلة (أي إنشاء قائمة تحتوي على قوائم أخرى)، فمثلًا:

>>> a = ['a', 'b', 'c']
>>> n = [1, 2, 3]
>>> x = [a, n]
>>> x
[['a', 'b', 'c'], [1, 2, 3]]
>>> x[0]
['a', 'b', 'c']
>>> x[0][1]
'b'

List Comprehensions

تقدّم List comprehensions طريقة مختصرة لإنشاء القوائم، ومن التطبيقات الشائعة هي إنشاء قوائم جديدة يكون فيها كل عنصر نتيجة لبعض العمليات المطبقة على كل عنصر في تسلسل آخر، أو إنشاء تسلسل فرعي يضمّ العناصر التي تطابق شرطًا معيّنًا.

لنفترض على سبيل المثال أنّنا نرغب في إنشاء قائمة بمربعات الأرقام، مثل:

>>> squares = []
>>> for x in range(10):
...     squares.append(x**2)
...
>>> squares
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

لاحظ أنّ الشيفرة السابقة تنشئ (أو تعيد كتابة) المتغيّر x والذي يبقى موجودًا بعد انتهاء الحلقة التكرارية. يمكن حساب قائمة مربّعات الأرقام دون أي مشاكل باستخدام:

squares = list(map(lambda x: x**2, range(10)))

أو باستخدام الصيغة المكافئة التالية وهي صيغة مختصرة وسهلة القراءة:

squares = [x**2 for x in range(10)]

تتكوّن list comprehensions من أقواس تضمّ تعبيرًا تتبعه عبارة for ويمكن أن تليها مجموعة من تعابير if أو for. تكون النتيجة قائمة جديدة تنشأ من معالجة التعبير في سياق عبارات for و if التي تليه. في المثال التالي تجمع list comprehension عناصر قائمتين مختلفتين إن كانت هذه العناصر غير متساوية:

>>> [(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]

الشيفرة السابقة مكافئة للشيفرة التالية:

>>> combs = []
>>> for x in [1,2,3]:
...     for y in [3,1,4]:
...         if x != y:
...             combs.append((x, y))
...
>>> combs
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]

لاحظ أنّ ترتيب عبارتي for و if متطابق في كلا المثالين السابقين. عند الحاجة إلى استخدام الصفوف (tuples) (مثل (x, y) في المثال السابق) فيجب أن يحاط التعبير بأقواس.

>>> vec = [-4, -2, 0, 2, 4]
>>> # إنشاء قائمة جديدة مع مضاعفة الأرقام
>>> [x*2 for x in vec]
[-8, -4, 0, 4, 8]
>>> # إنشاء قائمة جديدة مع استبعاد الأرقام السالبة
>>> [x for x in vec if x >= 0]
[0, 2, 4]
>>> # تطبيق دالة على جميع العناصر
>>> [abs(x) for x in vec]
[4, 2, 0, 2, 4]
>>> # استدعاء تابع مع كل العناصر
>>> freshfruit = ['  banana', '  loganberry ', 'passion fruit  ']
>>> [weapon.strip() for weapon in freshfruit]
['banana', 'loganberry', 'passion fruit']
>>> # إنشاء قائمة من صفوف ثنائية (الرقم، مربع الرقم)
>>> [(x, x**2) for x in range(6)]
[(0, 0), (1, 1), (2, 4), (3, 9), (4, 16), (5, 25)]
>>> # يجب أن يحاط الصفّ بأقواس، وإلا تطلق اللغة خطأً
>>> [x, x**2 for x in range(6)]
  File "<stdin>", line 1, in <module>
    [x, x**2 for x in range(6)]
               ^
SyntaxError: invalid syntax
>>> # دمج القوائم باستخدام عبارتين تكراريتين
>>> vec = [[1,2,3], [4,5,6], [7,8,9]]
>>> [num for elem in vec for num in elem]
[1, 2, 3, 4, 5, 6, 7, 8, 9]

يمكن أن تتضمن list comprehensions تعابير معقّدة ودوال متداخلة:

>>> from math import pi
>>> [str(round(pi, i)) for i in range(1, 6)]
['3.1', '3.14', '3.142', '3.1416', '3.14159']

List comprehensions متشعبة

يمكن لأول تعبير في list comprehension أن يكون تعبيرًا عامًّا، ويمكن أن يكون list comprehension آخر أيضًا.

يقدّم المثال التالي مصفوفة (matrix) بأبعاد ‎3×4، وذلك باستخدام قائمة تتضمن 3 قوائم كل واحدة منها مكوّنة من 4 عناصر:

>>> matrix = [
...     [1, 2, 3, 4],
...     [5, 6, 7, 8],
...     [9, 10, 11, 12],
... ]

ويمكن الاستفادة من list comprehensions في الحصول على منقولة المصفوفة (transpose):

>>> [[row[i] for row in matrix] for i in range(4)]
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]

وكما رأينا مسبقًا فإنّ list comprehension المتداخلة تُعالج في سياق عبارة for التي تليها، لذا فإنّ المثال السابق مكافئ للمثال التالي:

>>> transposed = []
>>> for i in range(4):
...     transposed.append([row[i] for row in matrix])
...
>>> transposed
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]

والمثال السابق بدوره مكافئ لما يلي:

>>> transposed = []
>>> for i in range(4):
...     transposed_row = []
...     for row in matrix:
...         transposed_row.append(row[i])
...     transposed.append(transposed_row)
...
>>> transposed
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]

ينصح باستخدام الدوال الداخلية بدلًا من عبارات التحكّم في التنفيذ المعقّدة، فعلى سبيل المثال يمكن تأدية العمليات السابقة باستخدام الدالة zip()‎:

>>> list(zip(*matrix))
[(1, 5, 9), (2, 6, 10), (3, 7, 11), (4, 8, 12)]

راجع فك تحزيم قائمة الوسائط للمزيد من المعلومات حول علامة (*) في السطر الأول من المثال السابق.

الدالة list()‎

يُمكن تحويل الكائنات القابلة للتّكرار إلى قوائم عبر استخدام الدّالة list()‎:

>>> list(range(1, 3))
[1, 2]
>>> list('ABCD')
['A', 'B', 'C', 'D']
>>> list((1, 2, 3))
[1, 2, 3]

الدوال التابعة للكائن list

list.sort()‎

فرز القائمة في مكانها وذلك بإجراء مقارنة بين عناصر القائمة بواسطة العامل ‎<‎ فقط.

list.append()‎

إضافة عنصرًا إلى نهاية القائمة.

list.extend()‎

إضافة مجموعة من العناصر إلى نهاية القائمة.

list.insert()‎

إضافة عنصرًا إلى القائمة في الموقع الذي يحدّده المستخدم.

list.remove()‎

حذف أول عنصر في القائمة تساوي قيمته القيمة التي يحدّدها المستخدم.

list.pop()‎

حذف العنصر في الموقع المحدّد من قبل المستخدم.

list.clear()‎

حذف جميع عناصر القائمة.

list.index()‎

تحديد موقع العنصر ضمن القائمة.

list.count()‎

تحديد عدد مرات تكرار العنصر الذي يحدّده المستخدم في القائمة.

list.reverse()‎

قلب ترتيب عناصر القائمة في مكانها.

list.copy()‎

إنشاء نسخة سطحية عن القائمة.

انظر أيضًا

مصادر