نظرة عامة على توابع القائمة في بايثون

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

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

ولكن ما هي توابع القائمة في بايثون بالضبط؟

قد تبدو كلمة “تابع” غريبة في البداية، ولكن لا تقلق: التوابع في بايثون تشبه إلى حد كبير دوال بايثون التقليدية، مثل print() أو sum() أو len().

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

إن التمييز المهم بين التوابع والدوال هو كيفية تشغيلها. يتم تنفيذ الدوال العادية عن طريق كتابة اسمها واستخدام الأقواس لتمرير بعض الوسائط (اختياريًا). ويبدو الأمر كما يلي:

result = some_function(argument1, argument2)

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

result = some_variable.some_method(argument1, argument2)

لاحظ النقطة قبل some_method؟ يشير هذا إلى أننا نستخدم تابع. يحدد نوع بيانات some_variable التوابع المتاحة.

فيما يلي مثال ملموس، حيث نقوم بتعريف قيم variable (قائمة) ثم نستدعي التابع append() الخاصة به مع 8 كحجة لها:

values = [1, 5, 10]
values.append(8)  # here we modify the "values" list

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

ملاحظة: في الأمثلة أدناه، نستخدم الترميز list.method_name() للإشارة إلى أن هذه التوابع تنتمي إلى القوائم. عند كتابة التعليمات البرمجية، تذكر استبدال list بالمتغير الفعلي الذي تريد استخدامه عند استدعاء التابع.

إضافة عناصر إلى قائمة بايثون باستخدام ()list.append

سنبدأ بإحدى عمليات القائمة الأكثر شيوعًا: سنضع العناصر في قائمة بايثون. يمكنك القيام بذلك باستخدام توابع القائمة list.append() وlist.insert() وlist.extend() – حيث يعمل كل تابع بطريقة مختلفة قليلاً.

على سبيل المثال، سيؤدي استخدام list.append(x) ببساطة إلى وضع العنصر x في نهاية القائمة. ألق نظرة على المثال أدناه:

numbers = [1, 2, 3, 4]
numbers.append(5)
print(numbers)
 
# output: [1, 2, 3, 4, 5]

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

هناك بعض الأشياء التي يجب مراعاتها هنا:

  • من أجل التبسيط، تحتوي قائمة الأرقام على أعداد صحيحة فقط. ولكن يمكن لقوائم بايثون أن تحتوي على عناصر من أي نوع – أو حتى أنواع متعددة في نفس القائمة. يعمل المثال بنفس الجودة إذا قمنا بتعديله إلى numbers.append("hello") أو numbers.append(True).
  • ربما كنت تتوقع أن يقوم التابع list.append() بإرجاع قيمة، مثل result = numbers.append(5). ومع ذلك، فإن معظم توابع القائمة في بايثون تحدث “في المكان”؛ حيث يتم تعديل القائمة الأصلية ولا يتم إرجاع أي شيء. في الواقع، إذا قمت بتنفيذ الكود، فسترى أن result تنتهي بقيمة None.

إدراج عناصر في قائمة بايثون باستخدام ()list.insert

تعمل list.insert() بشكل مشابه لـ list.append()، ولكنك تحتاج إلى توفير الفهرس الذي سيتم إدراج العنصر فيه في القائمة. ألق نظرة على المثال أدناه:

animals = ["cat", "dog", "fish"]
animals.insert(1, "monkey")
print(animals)
 
# output: ["cat", "monkey", "dog", "fish"]

لقد قمنا بإدراج العنصر “monkey” في الفهرس 1، والذي يتوافق مع الموضع الثاني في القائمة. (تذكر: في بايثون، تبدأ الفهارس من الصفر.) يتم دفع العنصرين الثاني والثالث (“dog” و”fish”، على التوالي) إلى النهاية لإفساح المجال للعنصر الذي يتم إدراجه.

من الميزات الرائعة لـ list.insert() أنك لست بحاجة إلى التحقق من حجم القائمة مسبقًا؛ فلا يتم رفع أي أخطاء إذا كان الفهرس أكبر من حجم القائمة. بدلاً من ذلك، يضع التابع list.insert() العنصر ببساطة في النهاية، وتعمل بشكل مشابه جدًا لـ list.append() في هذا الموقف. انظر إلى هذا المثال:

animals = ["cat", "dog", "fish"]
animals.insert(200, "monkey")
print(animals)
 
# output: ["cat", "dog", "fish", "monkey"]

على الرغم من أن القائمة الأصلية لا تحتوي على عنصر في الفهرس 200، إلا أن الكود لا يزال يضع العنصر الجديد “monkey” في نهايتها.

هناك ميزة مفيدة أخرى لـ list.insert() وهي استخدام فهرس 0، والذي يقوم دائمًا بإدراج العنصر في بداية القائمة.

إضافة عناصر متعددة إلى قائمة بايثون باستخدام ()list.extend

list.extend() هي طريقة أخرى لإضافة عناصر إلى قائمة بايثون. وهي مفيدة عندما تريد إضافة عناصر متعددة في وقت واحد.

من الأسهل فهم كيفية عمل list.extend() إذا حاولنا إضافة قائمة إلى قائمة أخرى. انظر ماذا يحدث:

things = ["John", 42, True]
other_things = [0.0, False]
things.append(other_things)
print(things)
 
# output: ["John", 42, True, [0.0, False]]

عندما نكتب things.append(other_things)، يتم اعتبار قائمة other_things كعنصر واحد، وننتهي بقائمة متداخلة. ولكن ماذا لو أردنا إضافة كل عنصر من other_things إلى قائمة things؟ هذا هو المكان الذي تكون فيه list.extend() مفيدة:

things = ["John", 42, True]
other_things = [0.0, False]
things.extend(other_things)
print(things)
 
# output: ["John", 42, True, 0.0, False]

لا توجد قوائم متداخلة! كما ترى، يقوم التابع list.extend() بإضافة كل عنصر فردي من القائمة التي تم تمريرها كحجة.

إزالة عنصر من قائمة بايثون باستخدام ()list.remove

ليس من المستغرب أن يتم استخدام التابع list.remove() لإزالة قيمة من القائمة. يتم ببساطة إزالة العنصر الأول الذي يطابق الوسيطة من القائمة. ولكن انتبه: يتم رفع خطأ إذا لم يكن العنصر موجودًا في القائمة!

يمكنك هنا رؤية التابع list.remove() أثناء العمل:

booleans = [True, False, True, True, False]
 
booleans.remove(False)   # Removes the first False value
print(booleans)
 
# output: [True, True, True, False]
 
booleans.remove(False)   # Removes the other False value
print(booleans)
 
# output: [True, True, True]
 
booleans.remove(False)   # ValueError! No more False values to remove

أخذ عنصر من قائمة بايثون باستخدام ()list.pop

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

فيما يلي التابع list.pop() في العمل:

fruits = ["apple", "orange", "banana", "peach"]
last_fruit = fruits.pop()  # takes the last element
print(last_fruit)
 
# output: "peach"
 
second_fruit = fruits.pop(1)  # takes the second element ( = index 1)
print(second_fruit)
 
# output: "orange"
 
print(fruits)  # only fruits that have not been "popped"
               # are still in the list
 
# output: ["apple", "banana"]

ربما لاحظت أن الفاكهة التي يتم “إخراجها” من القائمة يتم إرجاعها بالفعل، لذا يمكننا حفظها في متغيرات مثل last_fruit وsecond_fruit. وهذا يعني أنه يمكنك استخدام list.pop() لإزالة القيم من القوائم ولكن لا يزال بإمكانك الوصول إليها لاحقًا في الكود.

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

حذف جميع العناصر من قائمة بايثون باستخدام ()list.clear

هذه الطريقة مختصرة وواضحة: إذا قمت باستدعاء التابع list.clear()، فسيتم تجاهل جميع القيم وتصبح القائمة فارغة. إليك كيف يبدو هذا:

decimals = [0.1, 0.2, 0.3, 0.4, 0.5]
decimals.clear()  # remove all values!
print(decimals) 
 
# output: []

كما هو متوقع، تم إفراغ قائمة الأعداد العشرية بعد استدعاء التابع list.clear() .

حساب العناصر في قائمة بايثون باستخدام ()list.count

list.count() هو تابع قائمة يحسب عدد مرات ظهور وسيطتها داخل القائمة. يتم إرجاع هذا العدد بواسطة التابع، لذا يمكننا استخدام متغير لحفظه.

في المثال أدناه، نحسب عدد الطلاب الذين كانت درجاتهم في الامتحان تساوي 10.0:

grades = [7.8, 10.0, 7.9, 9.5, 10.0, 6.5, 9.8, 10.0]
n = grades.count(10.0)
print(n)
 
# output: 3

تحديد العناصر في قائمة بايثون باستخدام ()list.index

يعتبر التابع list.index() أكثر تعقيدًا بعض الشيء: عند إعطاء وسيطة، فإنها تعيد الموضع (الفهرس) الذي تظهر فيه الوسيطة في القائمة. ألق نظرة على هذا المثال:

friends = ["John", "James", "Jessica", "Jack"]
position = friends.index("Jessica")
print(position)
 
# output: 2

كما هو موضح أعلاه، قامت list.index() بإرجاع القيمة 2 بشكل صحيح، مما يشير إلى ظهور العنصر “Jessica” عند هذا الفهرس في القائمة.

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

friends = ["John", "James", "Jessica", "Jack"]
name = "Jessica"
 
if name in friends:
    position = friends.index(name)  # guaranteed to not raise an error
    print("Friend", name, "is at position", position)
else:
    print("Friend", name, "not in list")

قم بتغيير متغير الاسم إلى اسم غير موجود في القائمة، وستشاهد الكود يصل إلى كتلة else دون إثارة أي أخطاء!

إعادة ترتيب العناصر في قائمة بايثون باستخدام ()list.sort و()list.reverse

يمكن استخدام list.sort() وlist.reverse() لإعادة ترتيب العناصر في القائمة. وكما قد تتوقع، تقوم list.sort() بفرز القيم، بينما تقوم list.reverse() بعكس موضع كل قيمة في القائمة.

فيما يلي كيفية ظهور توابع قائمة بايثون هذه أثناء العمل:

values = [10, 4, -2, 1, 5]
 
values.reverse()
print(values)  # list is reversed
 
# output: [5, 1, -2, 4, 10]
 
values.sort()
print(values)  # list is sorted
 
# output: [-2, 1, 4, 5, 10]

إذا كنت تريد فرز القيم بترتيب تنازلي، فيمكنك أولاً استدعاء list.sort()، ثم list.reverse() بعد ذلك. ولكن هذه العملية شائعة جدًا لدرجة أن بايثون يسمح لك بإجراء كليهما في نفس الوقت: ما عليك سوى إضافة وسيطة reverse=True عند استدعاء list.sort(). ألق نظرة:

values = [10, 4, -2, 1, 5]
 
values.sort(reverse=True)
print(values)  # list is sorted in reverse order
 
# output: [10, 5, 4, 1, -2]

ملاحظة: لفرز قائمة في بايثون، يجب أن تكون قادرًا على مقارنة القيم فيما بينها ومعرفة القيم الأكبر من غيرها. وهذا يعني أنه لا يمكنك فرز قائمة تحتوي على أنواع بيانات متعددة، مثل السلاسل والأرقام. لا معنى للسؤال عما إذا كان الرقم 10 أكبر من السلسلة “جون”!

إنشاء نسخة مستقلة من قائمة بايثون باستخدام ()list.copy

تُستخدم list.copy() لإنشاء نسخة مستقلة من القائمة. وهذا مهم لأن العديد من المتغيرات قد تشير إلى نفس القائمة. في هذه الحالة، لا تكون المتغيرات نسخًا مستقلة، بل هي ببساطة مراجع لنفس كائن القائمة الأساسي.

لفهم هذا المفهوم بشكل أفضل، انظر إلى الكود أدناه:

values_01 = [1, 2, 3, 4]
values_02 = values_01  # not an actual copy: same list object!
 
values_02.append(5)  # we modify the "values_02" list...
print(values_01)     # ... but changes appear also in "values_01"
                     #     because they reference the same list!
 
# output: [1, 2, 3, 4, 5]

يفاجئ هذا العديد من الوافدين الجدد إلى Python، لأنهم يتوقعون ألا تتغير قائمة values_01 عند إضافة شيء إلى values_02. ولكن في الواقع، كلتا القائمتين values_01 وvalues_02 عبارة عن مراجع لنفس القائمة الأساسية!

الطريقة الصحيحة لإنشاء قوائم مستقلة هي استخدام التابع list.copy() :

values_01 = [1, 2, 3, 4]
values_02 = values_01.copy()  # create an independent copy!
 
values_02.append(5)  # we modify the "values_02" list...
print(values_01)     # ... and changes DO NOT appear in "values_01"
                     #     because it is a copy!
 
# output: [1, 2, 3, 4]

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

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

اترك تعليقاً

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

Scroll to Top

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

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

Continue reading