الرئيسية تعليم لغات البرمجة الصفوف والمجموعات في بايثون: Tuples و Sets للمبتدئين

الصفوف والمجموعات في بايثون: Tuples و Sets للمبتدئين

amr gamal سبتمبر 14, 2026

في الدروس السابقة، تعرفنا على القوائم (Lists) وكيفية استخدامها لتخزين مجموعة من البيانات التي يمكن تعديلها بحرية. لكن البرمجة الحقيقية تتطلب هياكل بيانات أكثر تنوعاً تتناسب مع حالات استخدام مختلفة. في هذا الدرس، سنتناول نوعين أساسيين آخرين من هياكل البيانات في لغة بايثون وهما: الصفوف (Tuples) والمجموعات (Sets).

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

ما هي الصفوف (Tuples) ولماذا نستخدمها؟

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

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

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

كيفية إنشاء واستخدام Tuples في بايثون

يتم إنشاء الصف باستخدام الأقواس الهلالية العادية () بدلاً من الأقواس المربعة [] الخاصة بالقوائم. لنلق نظرة على مثال عملي يوضح كيفية إنشاء صف وكيفية التعامل مع عناصره:

# إنشاء صف يمثل إعدادات الاتصال بقاعدة بيانات
database_config = ("localhost", 5432, "admin", "secure_pass_123")

# الوصول إلى العناصر باستخدام الفهارس (Indexes) تماماً مثل القوائم
print(database_config[0])  # النتيجة: localhost
print(database_config[1])  # النتيجة: 5432

# محاولة تعديل عنصر داخل الصف ستؤدي إلى خطأ
# database_config[1] = 3306  # سيظهر خطأ من نوع TypeError

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

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

ما هي المجموعات (Sets) في بايثون؟

ننتقل الآن إلى النوع الثاني وهو المجموعة (Set). المجموعة في بايثون تختلف جذرياً عن القوائم والصفوف من حيث قاعدتين أساسيتين:

  • العناصر غير مرتبة (Unordered): لا يوجد فهرس (Index) محدد للعناصر، ولا يمكنك ضمان الترتيب الذي أُدخلت به.
  • العناصر فريدة ولا تتكرر (Unique): إذا قمت بإدخال عنصر مكرر داخل مجموعة، فستقوم بايثون بحذف التكرار تلقائياً والاحتفاظ بنسخة واحدة فقط.

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

كيفية إنشاء واستخدام Sets في بايثون

تُنشأ المجموعات باستخدام الأقواس المعقوفة {} أو باستخدام الدالة المدمجة set(). دعونا نرى مثالاً عملياً يوضح ميزة عدم تكرار العناصر وكيفية إدارة المجموعات:

# قائمة تسجيل الحضور تحتوي على أسماء مكررة
attendees_list = ["أحمد", "فاطمة", "محمد", "أحمد", "سارة", "فاطمة"]

# تحويل القائمة إلى مجموعة لإزالة التكرار والحصول على الحضور الفريد
unique_attendees = set(attendees_list)
print(unique_attendees)  # النتيجة قد تبدو هكذا: {'محمد', 'سارة', 'أحمد', 'فاطمة'} (الترتيب عشوائي)

# إضافة عنصر جديد للمجموعة
unique_attendees.add("خالد")

# محاولة إضافة عنصر موجود مسبقاً (لن يتسبب في خطأ، لكنه لن يُضاف مجدداً)
unique_attendees.add("أحمد")

print(unique_attendees)

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

العمليات الرياضية على المجموعات (Set Operations)

تتميز المجموعات بدعمها القوي للعمليات الرياضية الخاصة بنظرية المجموعات، وهي مفيدة جداً في معالجة البيانات النصية أو الرقمية. إليك أهم ثلاث عمليات:

  • الاتحاد (Union): يجمع عناصر المجموعتين معاً بدون تكرار (يُستخدم الرمز | أو الدالة .union()).
  • التقاطع (Intersection): يجد العناصر المشتركة الموجودة في المجموعتين معاً (يُستخدم الرمز & أو الدالة .intersection()).
  • الفرق (Difference): يجد العناصر الموجودة في المجموعة الأولى وليست في الثانية (يُستخدم الرمز -).

لنطبق ذلك بمثال عملي يوضح كيفية مقارنة المهارات البرمجية:

# مهارات مطور الألعاب
game_developer = {"Python", "C++", "C#"}

# مهارات مطور الذكاء الاصطناعي
ai_developer = {"Python", "R", "SQL"}

# 1. إيجاد المهارات المشتركة بين الاثنين (التقاطع)
common_skills = game_developer & ai_developer
print("المهارات المشتركة:", common_skills)  # النتيجة: {'Python'}

# 2. جمع كل المهارات الفريدة للفئتين (الاتحاد)
all_skills = game_developer | ai_developer
print("كل المهارات المتاحة:", all_skills)

# 3. المهارات الخاصة بمطور الألعاب فقط ولا يمتلكها مطور الذكاء الاصطناعي (الفرق)
game_only_skills = game_developer - ai_developer
print("مهارات الألعاب البحتة:", game_only_skills)  # النتيجة: {'C#', 'C++'}

من خلال هذا المثال، يمكنك ملاحظة كيف توفر المجموعات طريقة نظيفة وواضحة جداً لح-ل مشاكل مقارنة البيانات المعقدة بسطر برمجي واحد، ودون الحاجة لكتابة حلقات تكرارية (Loops) طويلة ومعقدة.

أخطاء شائعة يقع فيها المبتدئون

أثناء التعامل مع Tuples و Sets، يقع المبرمجون الجدد غالباً في بعض الفخاخ البسيطة التي يمكن تجنبها بمعرفة طبيعة هذه الهياكل:

  • محاولة استخدام الفهارس مع المجموعات: تذكر دائماً أن المجموعات (Sets) غير مرتبة ولا تحتوي على فهارس. كتابة my_set[0] ستؤدي فوراً إلى ظهور خطأ TypeError: 'set' object is not subscriptable. إذا أردت الوصول لعنصر داخل مجموعة، يجب تحويلها إلى قائمة أو صف أولاً، أو المرور عليها باستخدام حلقة تكرار.
  • إنشاء مجموعة فارغة بطريقة خاطئة: إذا كتبت empty_set = {} فإن بايثون لن تنشئ مجموعة فارغة، بل ستنشئ قاموساً فارغاً (Dictionary). لإنشاء مجموعة فارغة صحيحة، يجب استخدام الدالة empty_set = set().
  • الخلط بين قابلية التعديل: تذكر أن الصفوف (Tuples) ثابتة الهيكل الخارجي، بينما المجموعات (Sets) قابلة للتعديل (يمكنك إضافة وحذف عناصر منها، لكن العناصر بحد ذاتها يجب أن تكون من أنواع بيانات ثابتة غير قابلة للتعديل مثل النصوص والأرقام والصفوف).

خلاصة الدرس

الصفوف والمجموعات هي أدوات أساسية تمنحك تحكماً أكبر بكفاءة وسلوكية البيانات في برامج بايثون. استخدم الصفوف (Tuples) عندما تريد حماية البيانات ومنع تعديلها مع ضمان أداء أسرع، واستخدم المجموعات (Sets) عندما تحتاج حصرياً إلى تصفية البيانات المكررة أو إجراء عمليات المقارنة الرياضية المتقدمة. في الدرس القادم، سنتعمق في القواميس (Dictionaries) وكيفية تخزين البيانات على شكل أزواج مرتبة من المفتاح والقيمة.

الكاتب
عمرو جمال

محرر متخصص في تطوير قوالب بلوجر وووردبريس وتقديم شروحات التقنية. أقدم حلولاً مبتكرة لتصميم مواقع عصرية وجذابة.