الصفوف في بايثون (Tuples)
بعد أن تعلمنا القوائم (Lists) المرنة والقابلة للتعديل، حان الوقت للتعرف على الصفوف (Tuples) - وهي نوع من هياكل البيانات مشابه للقوائم لكن مع فرق جوهري: لا يمكن تعديلها بعد إنشائها. قد يبدو هذا قيداً، لكنه في الواقع ميزة أمان قوية.
تخيل أن لديك إحداثيات نقطة (x, y) أو تاريخ (يوم، شهر، سنة). هذه بيانات لا يجب أن تتغير بالخطأ أثناء تشغيل البرنامج. الصفوف توفر هذه الحماية بشكل طبيعي.
1. ما هي الصفوف؟
الصف (Tuple) هو مجموعة مرتبة وغير قابلة للتعديل من العناصر. يُعرف باستخدام الأقواس الدائرية () بدلاً من المربعة.
| الخاصية | List (قائمة) | Tuple (صف) |
|---|---|---|
| الرمز | [] |
() |
| قابلية التعديل | نعم (Mutable) | لا (Immutable) |
| الأداء | أبطأ قليلاً | أسرع |
| الاستخدام | بيانات متغيرة | بيانات ثابتة |
2. إنشاء الصفوف
# صف فارغ
empty_tuple = ()
# صف بعنصر واحد (لاحظ الفاصلة!)
single = (42,) # الفاصلة ضرورية
not_tuple = (42) # هذا int وليس tuple!
# صف بعدة عناصر
coordinates = (10, 20)
rgb_color = (255, 128, 0)
person = ("أحمد", 25, "القاهرة")
# صف بدون أقواس (Tuple Packing)
point = 3, 4, 5
# تحويل قائمة إلى صف
my_list = [1, 2, 3]
my_tuple = tuple(my_list)
print(f"صف فارغ: {empty_tuple}")
print(f"عنصر واحد: {single}, النوع: {type(single)}")
print(f"ليس صفاً: {not_tuple}, النوع: {type(not_tuple)}")
print(f"الإحداثيات: {coordinates}")
print(f"اللون: {rgb_color}")
print(f"الشخص: {person}")
print(f"النقطة: {point}")
(value,). بدونها، بايثون تعتبره تعبيراً عادياً بين أقواس.
3. الوصول لعناصر الصف
الوصول لعناصر الصف يعمل بنفس طريقة القوائم: الفهرسة والتقطيع.
colors = ("Red", "Green", "Blue", "Yellow", "Purple")
print(f"الأول: {colors[0]}")
print(f"الأخير: {colors[-1]}")
print(f"من 1 إلى 3: {colors[1:4]}")
print(f"معكوس: {colors[::-1]}")
# التحقق من الوجود
print(f"\n'Blue' موجود؟ {'Blue' in colors}")
print(f"عدد العناصر: {len(colors)}")
4. تفكيك الصفوف (Tuple Unpacking)
من أقوى ميزات الصفوف هي التفكيك، حيث يمكنك تعيين كل عنصر لمتغير منفصل في سطر واحد.
# تفكيك أساسي
person = ("أحمد", 25, "القاهرة")
name, age, city = person
print(f"الاسم: {name}")
print(f"العمر: {age}")
print(f"المدينة: {city}")
# تبديل قيم متغيرين
a, b = 10, 20
print(f"\nقبل التبديل: a={a}, b={b}")
a, b = b, a
print(f"بعد التبديل: a={a}, b={b}")
# تفكيك مع * (للحصول على الباقي)
numbers = (1, 2, 3, 4, 5)
first, *middle, last = numbers
print(f"\nالأول: {first}")
print(f"الوسط: {middle}")
print(f"الأخير: {last}")
5. الدوال التي ترجع Tuple
كثير من الدوال المدمجة ترجع صفوفاً، وكذلك عندما ترجع عدة قيم من دالة.
# دالة تُرجع عدة قيم (tuple)
def get_min_max(numbers):
return min(numbers), max(numbers)
data = [5, 2, 8, 1, 9, 3]
minimum, maximum = get_min_max(data)
print(f"الأصغر: {minimum}, الأكبر: {maximum}")
# divmod تُرجع tuple
quotient, remainder = divmod(17, 5)
print(f"17 / 5 = {quotient} والباقي {remainder}")
6. متى نستخدم Tuple بدلاً من List؟
- بيانات ثابتة: إحداثيات، تواريخ، ألوان RGB
- مفاتيح القواميس: الصفوف يمكن استخدامها كمفاتيح (القوائم لا)
- إرجاع عدة قيم من دالة: أوضح وأنظف
- الأداء: أسرع قليلاً من القوائم
- الأمان: حماية البيانات من التعديل العرضي
7. أفضل الممارسات
- استخدم Tuple للبيانات الثابتة
- استفد من التفكيك لكود أنظف
- استخدم الفاصلة في الصف أحادي العنصر
- لا تحاول تعديل عناصر الصف
- لا تنس الفاصلة في
(x,) - لا تستخدم Tuple لبيانات تحتاج تعديل
ملخص الدرس
- الصفوف مجموعات مرتبة غير قابلة للتعديل
- تُنشأ باستخدام الأقواس
() - الصف أحادي العنصر يحتاج فاصلة
(x,) - التفكيك يسمح بتعيين العناصر لمتغيرات منفصلة
- أسرع وأكثر أماناً من القوائم للبيانات الثابتة
الخطوة التالية
تعلم القواميس (Dictionaries) لتخزين أزواج المفتاح-القيمة
الدرس التالي: القواميس (Dictionaries)