كيفية الحصول على فهرس عنصر في قائمة في بايثون

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

دعونا نرى مثالاً لقائمة بايثون.

>>> names = ["Jane", "James", "Matt", "Ashley", "Oliver"]
>>> type(names)
list

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

يمكننا استخدام التابع index() للعثور على فهرس العنصر.

>>> names = ["Jane", "James", "Matt", "Ashley", "Oliver"]
>>> names.index("Matt")
2

يبدأ الفهرس من 0. وبما أن “Matt” هو العنصر الثالث في قائمة names، فإن فهرسه هو 2.

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

تعتبر الأمثلة والخبرة العملية ضرورية لتعلم بايثون أو أي لغة برمجة أخرى. يحتوي موقع LearnPython.com على العديد من الدورات التدريبية والمسارات التفاعلية التي تقدم تجربة تعليمية نشطة مع التمارين. تركز دورة “هياكل بيانات بايثون في الممارسة العملية” على هياكل البيانات المضمنة في بايثون: القائمة، والتوبل، والقاموس، والمجموعة. تحتوي الدورة على 118 تمرينًا تفاعليًا لحل مشكلات البرمجة الأساسية باستخدام هياكل البيانات الأساسية.

كيفية استخدام التابع ()index

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

نظرًا لأن القوائم قد تحتوي على عناصر مكررة، فقد يكون هناك تكرارات متعددة للعنصر الذي نبحث عنه. في مثل هذه الحالات، يقوم التابع index() بإرجاع مؤشر التكرار الأول لهذا العنصر. دعنا نراجع مثالاً يوضح ذلك.

>>> names = ["Jane", "James", "Matt", "Ashley", "Oliver", "James"]
>>> names.index("James")
1

هناك قيمتان لـ “James” في قائمة الأسماء أعلاه. عندما نستخدم التابع index() للحصول على مؤشر “James”، فإنها تعيد القيمة 1، وهو مؤشر أول ظهور لـ “James”.

عندما لا يكون العنصر موجودًا في قائمة فهرس

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

>>> names = ["Jane", "James", "Matt", "Ashley", "Oliver", "James"]
>>> names.index("Alex")
ValueError: 'Alex' is not in list

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

>>> names = ["Jane", "James", "Matt", "Ashley", "Oliver", "James"]
>>> items_to_check = ["Matt", "Alex"]
>>> for item in items_to_check:
>>>      try:
>>>        print(f"The index of {item} is {names.index(item)}.")
>>>     except ValueError:
>>>        print(f"{item} is not in the list.")
The index of Matt is 2.
Alex is not in the list.

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

>>> names = ["Jane", "James", "Matt", "Ashley", "Oliver", "James"]
>>> items_to_check = ["Matt", "Alex"]
>>> for item in items_to_check:
>>>      if item in names:
>>>        print(f"The index of {item} is {names.index(item)}.")
The index of Matt is 2.

معلمات start وstop

يمكن أيضًا استخدام التابع index() للحصول على فهرس عنصر في تسلسل فرعي معين من قائمة بايثون. نقوم بتعريف تسلسل فرعي للبحث باستخدام معلمات start وstop. على سبيل المثال، إذا أردنا البحث عن عنصر في أول 5 عناصر، فإننا نضبط قيم معلمات البدء والتوقف على 0 و5 على التوالي.

يبحث كتلة التعليمات البرمجية التالية عن “Oliver” في التسلسل الفرعي الذي يبدأ من العنصر الأول (الفهرس 0) وينتهي بالعنصر الثالث (الفهرس 2). الحد الأعلى حصري، لذا فإن التسلسل الفرعي المحدد بواسطة 0 و3 يتضمن فقط العناصر “Jane” و”James” و”Matt”.

>>> names = ["Jane", "James", "Matt", "Ashley", "Oliver", "James"]
>>> names.index("Oliver", 0, 3)
ValueError: 'Oliver' is not in list

لنبدأ الآن بالبحث عن “Oliver” في الجزء الثاني من القائمة.

>>> names = ["Jane", "James", "Matt", "Ashley", "Oliver", "James"]
>>> names.index("Oliver", 3, 6)
4

في كتلة التعليمات البرمجية أعلاه، نتحقق من تسلسل “Ashley” و”Oliver” و”James”. ورغم أن “Oliver” هو العنصر الثاني في هذا التسلسل، فإن التابع index() يعيد 4، وهو مؤشر “Oliver” في القائمة بأكملها. وحتى عندما نبحث عن عنصر في تسلسل فرعي، يتم حساب المؤشر المُرجع بالنسبة إلى بداية التسلسل الكامل (أي القائمة بأكملها) بدلاً من وسيطة البداية.

عيوب التابع ()index في بايثون

يعيد التابع ()index الظهور الأول للعنصر في القائمة

لا يعيد التابع index() سوى الظهور الأول للعنصر الذي تم البحث عنه. إذا كان هناك العديد من العناصر ونريد معرفة مكانها جميعًا، فنحن بحاجة إلى نهج مختلف.

أحد الخيارات هو استخدام دالة enumerate في فهم القائمة. دعنا نرى مثالاً لتوضيح هذه الحالة باستخدام مثال رأيناه بالفعل.

>>> names = ["Jane", "James", "Matt", "Ashley", "Oliver", "James"]
>>> [i for i, e in enumerate(names) if e == "James"]
[1, 5]

تأخذ دالة enumerate المضمنة في بايثون عنصرًا قابلًا للتكرار وحجة start اختيارية. وتتكرر على العنصر القابل للتكرار مع تتبع العدد. يمكن استخدام قيمة العدد كمؤشر للعنصر. القيمة الافتراضية لحجة start الاختيارية هي 0، وهو ما نحتاجه عند العمل على القوائم لأن مؤشر قائمة بايثون يبدأ أيضًا من 0.

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

>>> names = ["Jane", "James", "Matt", "Ashley", "Oliver", "James"]
>>> [i for i, e in enumerate(names[3:]) if e == "James"]
[2]

من المهم ملاحظة أن قيمة مؤشر الإرجاع أعلاه نسبية لنقطة بداية التسلسل الفرعي. وذلك لأن دالة enumerate تبدأ العد من 0. يمكننا تخصيصها للعثور على قيمة المؤشر نسبة إلى العنصر الأول في القائمة باستخدام معلمة start لدالة enumerate.

>>> names = ["Jane", "James", "Matt", "Ashley", "Oliver", "James"]
>>> [i for i, e in enumerate(names[3:], start=3) if e == "James"]
[5]

البحث في قائمة باستخدام حلقة for

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

>>> names = ["Jane", "James", "Matt", "Ashley", "Oliver", "James"]
>>> james_index = []
>>> count = [0]
>>>
>>> for item in names:
>>>      if item == "James":
>>>        james_index.append(count)
>>>     count += 1
>>>
>>> james_index
[1, 5]

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

التعقيد الزمني الخطي لطريقة ()index

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

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

الاستفادة من قوائم بايثون

قائمة بايثون هي بنية بيانات أساسية. في هذه المقالة، تعلمنا عن التابع index() للقوائم. هناك العديد من التوابع الأخرى التي يمكننا استخدامها في القوائم مثل append وinsert. من المهم معرفة هذه التوابع لاستخدام القوائم بكفاءة وبشكل صحيح.

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

إذن لماذا الانتظار؟ ابدأ في تعلم بايثون اليوم!


اكتشاف المزيد من بايثون العربي

اشترك للحصول على أحدث التدوينات المرسلة إلى بريدك الإلكتروني.

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *

Scroll to Top

اكتشاف المزيد من بايثون العربي

اشترك الآن للاستمرار في القراءة والحصول على حق الوصول إلى الأرشيف الكامل.

Continue reading