هياكل البيانات في بايثون: دليلك الشامل للبدء 🚀

مرحباً بك في عالم هياكل البيانات! إذا كنت تتخيل أن البرمجة هي مثل بناء منزل، فإن هياكل البيانات (Data Structures) هي الطوب والأدوات التي سنبني بها. في هذا الدرس، سنتعرف على هذه "الأدوات" الذكية التي تقدمها لنا لغة بايثون، وكيف تجعل تنظيم ومعالجة المعلومات أمراً سهلاً وفعّالاً.


ما هي هياكل البيانات؟ 🤔

ببساطة شديدة، هياكل البيانات هي طريقة لتخزين وتنظيم البيانات داخل ذاكرة الكمبيوتر، بحيث يمكن الوصول إليها وتعديلها واستخدامها بكفاءة.

لنتخيل المثال التالي: لديك مجموعة من الأرقام: 5, 1, 9, 3. يمكنك كتابتها على ورقة بشكل عشوائي، أو يمكنك كتابتها في قائمة مرتبة. القائمة المرتبة هي "هيكل بيانات" بسيط سهل القراءة والاستخدام.

لماذا نهتم بها؟

  • التنظيم: بدلاً من تخزين كل متغير لوحده، نجمع البيانات ذات الصلة معاً.
  • الكفاءة: هياكل البيانات الجيدة توفر وقت وجهد المعالجة.
  • الحلول: العديد من المشاكل البرمجية يكون حلها الأمثل مرتبطاً باختيار الهيكل المناسب للبيانات.

الأنواع الأساسية لهياكل البيانات في بايثون 🗂️

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

  1. هياكل البيانات المضمنة (Built-in): هياكل جاهزة لا تحتاج لاستيراد أي مكتبة إضافية.
  2. هياكل بيانات المعيار (Collections): هياكل متقدمة أكثر، تحتاج لاستيراد وحدة collections (وسنتعرف عليها لاحقاً في الكورس).

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


1. القائمة (List) 📃

القائمة هي الهيكل الأكثر مرونة وشيوعاً. يمكنك تخيلها كـ صف مرتب يمكنه تخزين أي نوع من البيانات (أرقام، نصوص، الخ)، ويمكن تغيير محتوياته بعد الإنشاء.

خصائصها:

  • مرتبة: تحفظ ترتیب إضافة العناصر.
  • قابلة للتغيير (Mutable): يمكنك إضافة، حذف، أو تعديل العناصر بعد الإنشاء.
  • تسمح بالتكرار: يمكن أن تحتوي على عناصر مكررة.

مثال عملي:

# إنشاء قائمة لتخزين أسماء الطلاب
students = ["أحمد", "سارة", "خالد", "فاطمة"]

# طباعة القائمة كاملة
print(students)  # الناتج: ['أحمد', 'سارة', 'خالد', 'فاطمة']

# الوصول لعنصر محدد (التعداد يبدأ من الصفر)
print(students[0])  # الناتج: أحمد
print(students[2])  # الناتج: خالد

# إضافة طالب جديد إلى نهاية القائمة
students.append("نور")
print(students)  # الناتج: ['أحمد', 'سارة', 'خالد', 'فاطمة', 'نور']

# تعديل اسم طالب موجود
students[1] = "سارة محمد"
print(students)  # الناتج: ['أحمد', 'سارة محمد', 'خالد', 'فاطمة', 'نور']

2. المجموعة (Set) 🧺

المجموعة هي هيكل بيانات غير مرتب مصمم لتخزين عناصر فريدة (لا تكرار فيها). مثالية عندما لا يهمك الترتيب، ولكن يهمك التأكد من عدم وجود تكرار.

خصائصها:

  • غير مرتبة: لا تحفظ ترتیب العناصر.
  • قابلة للتغيير: يمكن إضافة وحذف العناصر.
  • لا تسمح بالتكرار: تزيل التكرار تلقائياً.
  • مفيدة للعمليات الرياضية مثل الاتحاد والتقاطع.

مثال عملي:

# إنشاء مجموعة لتخزين أرقام الهواتف الفريدة في مسابقة
winner_numbers = {105, 207, 105, 300, 207}

# لاحظ أن بايثون ستزيل التكرار تلقائياً
print(winner_numbers)  # الناتج: {207, 105, 300} (قد يظهر بترتيب مختلف)

# محاولة إضافة رقم موجود مسبقاً
winner_numbers.add(105)
print(winner_numbers)  # الناتج: {207, 105, 300} (لم يتغير، الرقم موجود)

# إضافة رقم جديد
winner_numbers.add(555)
print(winner_numbers)  # الناتج: {207, 105, 300, 555}

3. القاموس (Dictionary) 📖

القاموس هو هيكل بيانات قوي يعتمد على المفتاح والقيمة (Key-Value Pair). يمكنك تخيله كقاموس لغوي حقيقي: تبحث عن "كلمة" (المفتاح) لتحصل على "معناها" (القيمة).

خصائصه:

  • غير مرتب (في إصدارات بايثون القديمة، لكنه يحفظ الترتيب من بايثون 3.7 فما فوق).
  • قابل للتغيير.
  • المفاتيح يجب أن تكون فريدة، بينما يمكن تكرار القيم.

مثال عملي:

# إنشاء قاموس لتخزين معلومات طالب
student_info = {
    "name": "أحمد",
    "age": 20,
    "major": "علوم الحاسب",
    "GPA": 3.8
}

# طباعة القاموس كاملاً
print(student_info)

# الوصول لقيمة باستخدام مفتاحها
print(student_info["name"])  # الناتج: أحمد
print(student_info["GPA"])   # الناتج: 3.8

# إضافة معلومات جديدة (مفتاح وقيمة جديدان)
student_info["university"] = "الجامعة الافتراضية"
print(student_info)

# تعديل قيمة موجودة
student_info["age"] = 21
print(student_info["age"])  # الناتج: 21

4. التابِل (Tuple) 📦

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

خصائصه:

  • مرتب.
  • غير قابل للتغيير: هذا يجعله أسرع وأكثر أماناً في بعض الحالات.
  • يسمح بالتكرار.

مثال عملي:

# إنشاء تابِل لتخزين إحداثيات نقطة ثابتة على الخريطة
point_coordinates = (10, 20)

print(point_coordinates)  # الناتج: (10, 20)
print(point_coordinates[0])  # الناتج: 10 (الوصول للقراءة فقط مسموح)

# محاولة تعديل العنصر (سيفشل!)
# point_coordinates[0] = 15  # سيتسبب هذا في خطأ: TypeError

# يمكننا استخدام التابِل في أماكن تحتاج لثبات البيانات، مثل أيام الأسبوع
days_of_week = ("السبت", "الأحد", "الإثنين", "الثلاثاء", "الأربعاء", "الخميس", "الجمعة")
print(days_of_week[2])  # الناتج: الإثنين

خلاصة سريعة: كيف تختار الهيكل المناسب؟ 🎯

  • هل تحتاج ترتيباً وتغييراً؟ -> القائمة (List).
  • هل تحتاج عناصر فريدة بدون تكرار ولا يهمك الترتيب؟ -> المجموعة (Set).
  • هل تريد ربط بيانات بمفاتيف للبحث السريع؟ -> القاموس (Dictionary).
  • هل لديك بيانات ثابتة لا تتغير؟ -> التابِل (Tuple).