دليل تعلم بايثون مدخل إلى القوائم في بايثون 3


محمد الميداوي

القائمة هي بنية بيانات في بايثون، وهي عبارة عن تسلسل مُرتّب من العناصر قابل للتغيير (mutable).

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

القوائم في بايثون وغيرها من هياكل البيانات المركبة تساعد على تمثيل المجموعات، مثل مجموعة الملفات في مجلد على حاسوبك، أو قوائم التشغيل، ورسائل البريد الإلكتروني، وغير ذلك.

في المثال التالي، سننشئ قائمةً تحتوي على عناصر من نوع السلاسل النصية:

sea_creatures = ['shark', 'cuttlefish', 'squid', 'mantis shrimp', 'anemone']

عندما نطبع القائمة، فإنّ المخرجات ستشبه القائمة التي أنشأناها:

print(sea_creatures)    #  ['shark', 'cuttlefish', 'squid', 'mantis shrimp', 'anemone']

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

سنتعرف في هذه المقالة على القوائم وتوابعها وكيفية استخدامها.

مدخل إلى القوائم.jpg

فهرسة القوائم (Indexing Lists)

كل عنصر في القائمة يقابله رقم يمثل فهرسَ ذلك العنصر، والذي هو عدد صحيح، فهرس العنصر الأول في القائمة هو 0.

هذا تمثيل لفهارس القائمة sea_creatures:

shark cuttlefish squid shrimp anemone
0 1 2 3 4

يبدأ العنصر الأول، أي السلسلة النصية shark، عند الفهرس 0، وتنتهي القائمة عند الفهرس 4 الذي يقابل العنصر anemone.

نظرًا لأنّ كل عنصر في قوائم بايثون يقابله رقم فهرس، يمكننا الوصول إلى عناصر القوائم ومعالجتها كما نفعل مع أنواع البيانات المتسلسلة الأخرى.

يمكننا الآن استدعاء عنصر من القائمة من خلال رقم فهرسه:

print(sea_creatures[1])       #  cuttlefish

تتراوح أرقام الفهارس في هذه القائمة بين 0 و 4، كما هو موضح في الجدول أعلاه. المثال التالي يوضح ذلك:

sea_creatures[0] = 'shark'
sea_creatures[1] = 'cuttlefish'
sea_creatures[2] = 'squid'
sea_creatures[3] = 'mantis shrimp'
sea_creatures[4] = 'anemone'

إذا استدعينا القائمة sea_creatures برقم فهرس أكبر من 4، فسيكون الفهرس خارج النطاق، وسيُطلَق الخطأ IndexError:

print(sea_creatures[18])

والمخرجات ستكون:

IndexError: list index out of range

يمكننا أيضًا الوصول إلى عناصر القائمة بفهارس سالبة، والتي تُحسَب من نهاية القائمة، بدءًا من -1. هذا مفيد في حال كانت لدينا قائمة طويلة، وأردنا تحديد عنصر في نهايته.

بالنسبة لقائمة sea_creatures، تبدو الفهارس السالبة كما يلي:

shark cuttlefish squid shrimp anemone
-5 -4 -3 -2 -1

في المثال التالي، سنطبع العنصر squid باستخدام فهرس سالب:

print(sea_creatures[-3])     #  squid

يمكننا ضم (concatenate) عنصر يحتوي سلسلة نصية مع سلسلة نصبة أخرى باستخدام العامل +:

print('Sammy is a ' + sea_creatures[0])     # Sammy is a shark

لقد ضممنا السلسلة النصية Sammy is a مع العنصر ذي الفهرس 0. يمكننا أيضًا استخدام العامل + لضمّ قائمتين أو أكثر معًا (انظر الفقرة أدناه):

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

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

يمكننا استخدام الفهرسة لتغيير عناصر القائمة، عن طريق إسناد قيمة إلى عُنصر مُفهرس من القائمة. هذا يجعل القوائم أكثر مرونة، ويسهّل تعديل وتحديث عناصرها.

إذا أردنا تغيير قيمة السلسلة النصية للعنصر الموجود عند الفهرس 1، من القيمة cuttlefish إلى octopus، فيمكننا القيام بذلك على النحو التالي:

sea_creatures[1] = 'octopus'

الآن، عندما نطبع sea_creatures، ستكون النتيجة:

print(sea_creatures)    # ['shark', 'octopus', 'squid', 'mantis shrimp', 'anemone']

يمكننا أيضًا تغيير قيمة عنصر باستخدام فهرس سالب:

sea_creatures[-3] = 'blobfish'
print(sea_creatures)      #   ['shark', 'octopus', 'blobfish', 'mantis shrimp', 'anemone']

الآن استبدلنا بالسلسلة squid السلسلة النصية blobfish الموجودة عند الفهرس السالب ‎-3 (والذي يتوافق مع الفهرس الموجب 2).

اقتطاع القوائم (Slicing Lists)

يمكننا أيضا استدعاء عدة عناصر من القائمة. لنفترض أننا نرغب في طباعة العناصر الموجودة في وسط القائمة sea_creatures، يمكننا القيام بذلك عن طريق اقتطاع شريحة (جزء) من القائمة.

يمكننا باستخدام الشرائح استدعاء عدة قيم عن طريق إنشاء مجال من الفهارس مفصولة بنقطتين [x: y]:

print(sea_creatures[1:4])    # ['octopus', 'blobfish', 'mantis shrimp']

عند إنشاء شريحة، كما في [‎1: 4]، يبدأ الاقتطاع من العنصر ذي الفهرس الأول (مشمولًا)، وينتهي عند العنصر ذي الفهرس الثاني (غير مشمول)، لهذا طُبعَت في مثالنا أعلاه العناصر الموجودة في المواضع، 1، و 2، و 3.

إذا أردنا تضمين أحد طرفي القائمة، فيمكننا حذف أحد الفهرسَين في التعبير [x: y]. على سبيل المثال، إذا أردنا طباعة العناصر الثلاثة الأولى من القائمة sea_creatures، يمكننا فعل ذلك عن طريق كتابة:

print(sea_creatures[:3])     #  ['shark', 'octopus', 'blobfish']

لقد تم طبع العناصر من بداية القائمة حتّى العنصرٍ ذي الفهرس 3.

لتضمين جميع العناصر الموجودة في نهاية القائمة، سنعكس الصياغة:

print(sea_creatures[2:])    #  ['blobfish', 'mantis shrimp', 'anemone']

يمكننا أيضًا استخدام الفهارس السالبة عند اقتطاع القوائم، تمامًا كما هو الحال مع الفهارس الموجبة:

print(sea_creatures[-4:-2])         #  ['octopus', 'blobfish']
print(sea_creatures[-3:])           #  ['blobfish', 'mantis shrimp', 'anemone']

هناك معامل آخر يمكننا استخدامه في الاقتطاع، ويشير إلى عدد العناصر التي يجب أن يتم القفز عليها (أو الخطوة) بعد استرداد العنصر الأول من القائمة. حتى الآن، لقد أغفلنا المعامل stride، وستعطيه بايثون القيمة الافتراضية 1، ما يعني أنه سيتم استرداد كل العناصر الموجودة بين الفهرسَين المحددين.

ستكون لصياغة على الشكل التالي [x: y: z]، إذ يشير z إلى الخطوة (stride). في المثال التالي، سننشئ قائمة كبيرة، ثم نقتطعها، مع خطوة اقتطاع تساوي 2:

numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

print(numbers[1:11:2])       #  [1, 3, 5, 7, 9]

سيطبع التعبير numbers[‎1: 11: 2]‎ القيم ذات الفهارس المحصورة بين 1 (مشمولة) و 11 (غير مشمولة)، وسيقفز البرنامج بخطوتين كل مرة، ويطبع العناصر المقابلة.

يمكننا حذف المُعاملين الأوّليين، واستخدام الخطوة وحدها كمعامل وفق الصياغة التالية: [‎::z]:

print(numbers[::3])      #  [0, 3, 6, 9, 12]

عند طباعة القائمة ‎numbers مع تعيين الخطوة عند القيمة 3، فلن تُطبع إلا العناصر التي فهارسها من مضاعفات 3: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 يجعل استخدام الفهارس الموجبة والسالبة ومعامل الخطوة في اقتطاع القوائم التحكم في القوائم ومعالجتها أسهل وأكثر مرونة.

تعديل القوائم بالعوامل

يمكن استخدام العوامل لإجراء تعديلات على القوائم. سننظر في استخدام العاملين + و * ومقابليهما المركبين ‎+=‎ و ‎*=‎‎.

يمكن استخدام العامل + لضمّ (concatenate) قائمتين أو أكثر معًا:

sea_creatures = ['shark', 'octopus', 'blobfish', 'mantis shrimp', 'anemone']
oceans = ['Pacific', 'Atlantic', 'Indian', 'Southern', 'Arctic']

print(sea_creatures + oceans)

والمخرجات هي:

['shark', 'octopus', 'blobfish', 'mantis shrimp', 'anemone', 'Pacific', 'Atlantic', 'Indian', 'Southern', 'Arctic']

يمكن استخدام العامل + لإضافة عنصر (أو عدة عناصر) إلى نهاية القائمة. لكن تذكر أن تضع العنصر بين قوسين مربعين:

sea_creatures = sea_creatures + ['yeti crab']
print (sea_creatures)    #   ['shark', 'octopus', 'blobfish', 'mantis shrimp', 'anemone', 'yeti crab']

يمكن استخدام العامل * لمضاعفة القوائم (multiply lists). ربما تحتاج إلى عمل نُسِخٍ لجميع الملفات الموجودة في مجلد على خادم، أو مشاركة قائمة أفلام مع الأصدقاء؛ ستحتاج في هذه الحالات إلى مضاعفة مجموعات البيانات.

سنضاعف القائمة sea_creatures مرتين، والقائمة oceans ثلاث مرات:

print(sea_creatures * 2)
print(oceans * 3)

والنتيجة ستكون:

['shark', 'octopus', 'blobfish', 'mantis shrimp', 'anemone', 'yeti crab', 'shark', 'octopus', 'blobfish', 'mantis shrimp', 'anemone', 'yeti crab']
['Pacific', 'Atlantic', 'Indian', 'Southern', 'Arctic', 'Pacific', 'Atlantic', 'Indian', 'Southern', 'Arctic', 'Pacific', 'Atlantic', 'Indian', 'Southern', 'Arctic']

يمكننا باستخدام العامل * نسخ القوائم عدة مرات.

يمكننا أيضًا استخدام الشكلين المركبين للعاملين + و * مع عامل الإسناد =. يمكن استخدام العاملين المركبين ‎+=‎ و ‎*=‎ لملء القوائم بطريقة سريعة ومُؤتمتة. يمكنك استخدام هذين العاملين لملء القوائم بعناصر نائبة (placeholders) يمكنك تعديلها في وقت لاحق بالمدخلات المقدمة من المستخدم على سبيل المثال.

في المثال التالي، سنضيف عنصرًا إلى القائمة sea_creatures. سيعمل هذا العنصر مثل عمل العنصر النائب، ونود إضافة هذا العنصر النائب عدة مرات. لفعل ذلك، سنستخدم ‎+=‎ العامل مع الحلقة for.

for x in range(1,4):
    sea_creatures += ['fish']
    print(sea_creatures)

والمخرجات ستكون:

['shark', 'octopus', 'blobfish', 'mantis shrimp', 'anemone', 'yeti crab', 'fish']
['shark', 'octopus', 'blobfish', 'mantis shrimp', 'anemone', 'yeti crab', 'fish', 'fish']
['shark', 'octopus', 'blobfish', 'mantis shrimp', 'anemone', 'yeti crab', 'fish', 'fish', 'fish']

سيُضاف لكل تكرار في الحلقة for عنصر fish إلى القائمة sea_creatures.

العامل ‎*=‎ يتصرف بطريقة مماثلة:

sharks = ['shark']

for x in range(1,4):
    sharks *= 2
    print(sharks)

الناتج سيكون:

['shark', 'shark']
['shark', 'shark', 'shark', 'shark']
['shark', 'shark', 'shark', 'shark', 'shark', 'shark', 'shark', 'shark']

إزالة عنصر من قائمة

يمكن إزالة العناصر من القوائم باستخدام التعبير del. سيؤدي ذلك إلى حذف العنصر الموجود عند الفهرس المحدد.

سنزيل من القائمة sea_creatures العنصر octopus. هذا العنصر موجود عند الفهرس 1. لإزالة هذا العنصر، سنستخدم العبارة del ثم نستدعي متغير القائمة وفهرس ذلك العنصر:

sea_creatures =['shark', 'octopus', 'blobfish', 'mantis shrimp', 'anemone', 'yeti crab']

del sea_creatures[1]
print(sea_creatures)     #  ['shark', 'blobfish', 'mantis shrimp', 'anemone', 'yeti crab']

الآن، العنصر الموجود عند الفهرس 1، أي السلسلة النصية octopus، لم يعد موجودًا في قائمتنا.

يمكننا أيضًا تحديد مجال مع العبارة del. لنقل أننا نريد إزالة العناصر octopus، و blobfish و mantis shrimp معًا. يمكننا فعل ذلك على النحو التالي:

sea_creatures =['shark', 'octopus', 'blobfish', 'mantis shrimp', 'anemone', 'yeti crab']

del sea_creatures[1:4]
print(sea_creatures)     #  ['shark', 'anemone', 'yeti crab']

باستخدام مجال مع العبارة del، تمكنا من إزالة العناصر الموجودة بين الفهرسَين 1 (مشمول) و 4 (غير مشمول)، والقائمة أضحت مكوّنة من 3 عناصر فقط بعد إزالة 3 عناصر منها.

بناء قوائم من قوائم أخرى موجودة

يمكن أن تتضمّن عناصر القوائم قوائم أخرى، مع إدراج كل قائمة بين قوسين معقوفين داخل الأقواس المعقوفة الخارجية التابعة لقائمة الأصلية:

sea_names = [['shark', 'octopus', 'squid', 'mantis shrimp'],['Sammy', 'Jesse', 'Drew', 'Jamie']]

تسمى القوائم المُتضمّنة داخل قوائم أخرى بالقوائم المتشعبة (nested lists).

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

print(sea_names[1][0])    #  Sammy  
print(sea_names[0][0])    #  shark

فهرس القائمة الأولى يساوي 0، والقائمة الثانية فهرسُها 1. ضمن كل قائمة متشعبة داخلية، سيكون هناك فهارس منفصلة، والتي سنسميها فهارس ثانوية:

sea_names[0][0] = 'shark'
sea_names[0][1] = 'octopus'
sea_names[0][2] = 'squid'
sea_names[0][3] = 'mantis shrimp'

sea_names[1][0] = 'Sammy'
sea_names[1][1] = 'Jesse'
sea_names[1][2] = 'Drew'
sea_names[1][3] = 'Jamie'

عند العمل مع قوائم مؤلّفة من قوائم، من المهم أن تعي أنك ستحتاج إلى استخدام أكثر من فهرس واحد للوصول إلى عناصر القوائم المتشعبة.

خلاصة

القوائم هي نوع بيانات مرن يمكن تعديله بسهولة خلال أطوار البرنامج. غطينا في هذه المقالة الميزات والخصائص الأساسية لقوائم، بما في ذلك الفهرسة والاقتطاع والتعديل والضّم.

يمكنك تعلم المزيد عن القوائم من هاتين المقالتين:

هذه المقالة جزء من سلسة مقالات حول تعلم البرمجة في بايثون 3.

ترجمة -وبتصرّف- للمقال Understanding Lists in Python 3 لصاحبته Lisa Tagliaferri

اقرأ أيضًا





تفاعل الأعضاء


لا توجد أيّة تعليقات بعد



يجب أن تكون عضوًا لدينا لتتمكّن من التعليق

انشاء حساب جديد

يستغرق التسجيل بضع ثوان فقط


سجّل حسابًا جديدًا

تسجيل الدخول

تملك حسابا مسجّلا بالفعل؟


سجّل دخولك الآن