2.1القوائم والتوابع والقواميس والمجموعات
الأساسي في 30 ثانية
- أربع حاويات وأربع استعمالات : قائمة مرتبة قابلة للتعديل، وتابع مرتب ثابت، وقاموس بالمفاتيح، ومجموعة قيم فريدة — الحاوية الصحيحة للاستعمال الصحيح.
- القاموس هو الهيكل الملك : قائمة قواميس = 90 % من البيانات الحقيقية (API وCSV وJSON) — الوصول بالمفتاح، و.get() دون KeyError.
- النسخ ليس الإسناد : = يشارك، و.copy() ينسخ سطحيا، وdeepcopy() ينسخ الكل — تحقق بالاختبار على المتداخل.
حالة مستمرة — نبيل ومبيعات الجزائر
نبيل، محلل بيانات مبتدئ في الجزائر، يستلم تصديرا للمبيعات : قائمة سطور فيها تكرار، وزبناء يجب إيجادهم بالرمز، وإحداثيات GPS ثابتة وفئات يجب إزالة تكرارها. نسخته الأولى تبحث عن الزبناء باجتياز قائمة — بطيء وهش. أعاد البناء : المبيعات في قائمة قواميس (مفتاح لكل حقل)، ودليل الزبناء في قاموس مفهرس بالرمز مع .get()، والإحداثيات في توابع ثابتة، والفئات في مجموعة. هذا اللعب بالبيانات نفسه يعود في 2.2 (تقارير منسقة بسلاسل f-strings وحفظ JSON) و2.3 (كائنات Vente وClient) و2.4 (ملف غائب يُدبَّر بنظافة).
الخيط الرابط للمستوى 2 : لعب بيانات نبيل نفسه يعود في الدرس والمخطط والنص الجاهز وتحدي 48 ساعة — ويستمر في 2.2 و2.3 و2.4.
1. أربع حاويات وأربع طباع
التطبيقات الحقيقية تعالج مجموعات : قائمة مبيعات، ودليل زبناء، وفئات. تقدم بايثون أربع هياكل أساسية. القائمة (list) ([]) مرتبة وقابلة للتعديل — السكين السويسرية : الإضافة بـ append()، والوصول بـ index ابتداء من 0، والعنصر الأخير بـ [-1]. التابع (tuple) (()) مرتب لكن ثابت : مثالي للبيانات الجامدة (إحداثيات GPS، زوج ثابت) وقابل للاستعمال كمفتاح قاموس. القاموس (dict) ({}) يربط مفاتيح بقيم — دفتر العناوين : الوصول بالمفتاح لا بالموضع. المجموعة (set) (set()) لا تحفظ إلا قيما فريدة دون ترتيب : مثالية لإزالة التكرار واختبار الانتماء بـ in. نبيل يطبق ذلك : المبيعات في قائمة، والإحداثيات في تابع، والزبناء في قاموس، والفئات في مجموعة.
2. القاموس، الهيكل الملك
القاموس يستحق مكانته : client = {"nom": "نبيل", "wilaya": "الجزائر"}، والوصول client["nom"]، وخصوصا client.get("tel", "?") الذي يعيد قيمة افتراضية دون KeyError. قائمة القواميس تمثل 90 % من البيانات الحقيقية (سطور API وCSV وJSON) : كل سطر قاموس، والمجموع قائمة. نجتاز بـ .keys() (المفاتيح) و.values() (القيم) و.items() (الأزواج : for cle, valeur in d.items()). البحث بالمفتاح في قاموس مباشر ؛ والبحث بالمفتاح باجتياز قائمة بطيء وهش — قاعدة نبيل : حالما نبحث بمعرف، نفهرس في قاموس.
3. انسخ دون مشاركة (عودة اللافتات)
في بايثون، b = a لا ينسخ : الاسمان يشيران إلى الكائن نفسه — تعديل أحدهما يعدل الآخر. b = a.copy() ينسخ سطحيا (الكائنات المتداخلة تبقى مشتركة)، وcopy.deepcopy() ينسخ الكل بما فيه المتداخل. القاعدة : copy() لهيكل مسطح، وdeepcopy() للمتداخل — واختبار صغير للتحقق (id() أو تعديل تجريبي). نبيل يتذكر ذلك : « نسخته » من الجدول الشهري كانت تعدل الأصل حتى انتقل إلى deepcopy للسطور المتداخلة.
🔎 مثال ملموس — 🔎 مثال ملموس — إزالة التكرار وعد ولايات نبيل
المجموعة تزيل التكرار والفهم يعد، كما على مبيعات نبيل :
ventes = ["الجزائر", "وهران", "الجزائر", "البليدة", "وهران", "الجزائر"]
uniques = set(ventes)
comptes = {w: ventes.count(w) for w in uniques}
print(comptes) # {'الجزائر': 3, 'وهران': 2, 'البليدة': 1}
القراءة : set() تزيل التكرار وفهم القاموس يعد كل ولاية.
الدرس : التابع للمفاتيح المركبة الثابتة، والقاموس للوصول بالمفتاح.
مفردات القسم
- القائمة (list)
- مجموعة مرتبة وقابلة للتعديل، بين معقوفين : [1, 2, 3]. الإضافة بـ append()، والوصول بالفهرس من 0، و[-1] للأخير.
مثال بسيط: نبيل يرتب مبيعاته في قائمة يجتازها بـ for.
ما ليس كذلك: هيكل وصول بالمفتاح.
رد فعل: ترتيب يُجتاز = قائمة.
- التابع (tuple)
- مجموعة مرتبة لكن ثابتة (غير قابلة للتعديل)، بين قوسين : (lat, lon). يحمي البيانات الجامدة، وقابل للاستعمال كمفتاح قاموس.
مثال بسيط: إحداثيات GPS لنبيل توابع.
ما ليس كذلك: قائمة تُعدَّل عبر البرنامج.
رد فعل: بيان جامد = تابع.
- القاموس (dict)
- مجموعة أزواج مفتاح←قيمة، بين عاقفتين : {"nom": "نبيل"}. الوصول بالمفتاح، و.get() بافتراضي دون KeyError، والاجتياز بـ .items().
مثال بسيط: نبيل يجد زبونا برمزه عبر الدليل[code].
ما ليس كذلك: قائمة تُجتاز للبحث بمعرف.
رد فعل: البحث بمعرف = قاموس.
- المجموعة (set)
- مجموعة غير مرتبة من قيم فريدة : {1, 2, 3}. مثالية لإزالة التكرار (set(liste)) واختبار الانتماء بـ in.
مثال بسيط: نبيل يزيل تكرار الفئات بـ set(categories).
ما ليس كذلك: قائمة مكررة لاختبار الانتماء.
رد فعل: الفريدة أو الانتماء = مجموعة.
- النسخ (الإسناد / copy / deepcopy)
- = يشارك الكائن نفسه ؛ و.copy() ينسخ سطحيا (المتداخل مشترك) ؛ وcopy.deepcopy() ينسخ الكل بما فيه المتداخل.
مثال بسيط: نبيل يضاعف جدوله الشهري المتداخل بـ deepcopy.
ما ليس كذلك: إسناد يُظن نسخة.
رد فعل: متداخل يُضاعَف = deepcopy + اختبار.
في التطبيق — تطبيقيا — اختيار الهيكل الصحيح ومعالجته
- أنشئ قائمة مبيعات، وأضف (append) واحذف (remove) ورتب (sort) وصل بالفهرس. اجتزها بحلقة for.
- أنشئ قاموس « زبون » (الاسم والبريد والولاية). صل بالمفتاح، وأضف مفتاحا، واستعمل .get() بافتراضي، واجتز بـ .items().
- أنشئ تابع إحداثيات (ثابت) وحاول تعديله : لاحظ الخطأ. استنتج فائدة الثبات.
- أزل تكرار قائمة بـ set() ثم عد بفهم قاموس. تحقق من الفرق بين = و.copy() على قائمة.
نص جاهز — تبرير القاموس لزميل (30 ثانية)
« لمبيعات نبيل، أحتفظ بالقائمة للترتيب، لكن الزبناء مفهرسون في قاموس بالرمز : وصول مباشر، و.get() بافتراضي بدل التعطل، والاجتياز بـ .items(). اجتياز القائمة في كل بحث كان بطيئا وهشا — وهنا مقروء وفوري. »
يُقال مع عرض بحث بالرمز قبل (حلقة) وبعد (قاموس).
قالب للنسخ — دليل مفهرس وعد
ventes = [
{"client": "C01", "wilaya": "الجزائر", "montant": 1200},
{"client": "C02", "wilaya": "وهران", "montant": 800},
{"client": "C01", "wilaya": "الجزائر", "montant": 450},
]
annuaire = {"C01": {"nom": "نبيل", "wilaya": "الجزائر"}, "C02": {"nom": "لينا", "wilaya": "وهران"}}
for v in ventes:
client = annuaire.get(v["client"], {"nom": "مجهول"})
print(client["nom"], "->", v["montant"])
wilayas = [v["wilaya"] for v in ventes]
print({w: wilayas.count(w) for w in set(wilayas)})
تصدير يُزال تكراره
مبيعات نبيل تصل مكررة : set() على المعرفات، ثم قائمة قواميس منظفة.
دليل بالرمز
لكل زبون رمز فريد : قاموس مفهرس بالرمز، و.get() بافتراضي للرموز المجهولة.
إحداثيات ثابتة
نقاط التسليم توابع (lat, lon) : ثابتة، وقابلة للاستعمال كمفاتيح قاموس.
جدول شهري يُضاعَف
الملخص المتداخل يُضاعَف بـ deepcopy : وأصل الجزائر يبقى سليما.
✓ ممارسات جيدة
- الفهرسة في قاموس حالما نبحث بمعرف (لا اجتياز قائمة أبدا).
- استعمال .get() بافتراضي و.items() للاجتياز النظيف.
- النسخ بوعي : = يشارك، وcopy() سطحيا، وdeepcopy() للمتداخل.
✗ أخطاء شائعة
- البحث بالمفتاح باجتياز قائمة (بطيء وهش).
- استعمال dict[cle] دون .get() وتحمل KeyError.
- ظن أن = ينسخ الهيكل (فهو يشارك الكائن نفسه).
النقاط الأساسية
- القائمة = مرتبة + قابلة للتعديل ؛ والتابع = مرتب + ثابت.
- القاموس = أزواج مفتاح←قيمة (الدليل)، حاضر في كل مكان (JSON والإعداد) ؛ و.get() يتجنب KeyError.
- المجموعة = قيم فريدة، مثالية لإزالة التكرار والاختبار بـ in.
- الفهارس تبدأ من 0 ؛ و[-1] يعني الأخير ؛ و= يشارك، وcopy()/deepcopy() ينسخان.
تحدي 48 ساعة — طبق غدا
خذ تصديرا حقيقيا (تصدير نبيل أو تصديرك) : رتبه في قائمة قواميس، وفهرس دليلا في قاموس بالرمز مع .get()، وأزل تكرار عمود بـ مجموعة، وأثبت الفرق = مقابل .copy() على حالة متداخلة.
- أستطيع اختيار الهيكل الصحيح (قائمة، تابع، قاموس، مجموعة) مع مثال لكل منها.
- أعرف الفهرسة في قاموس واستعمال .get() والاجتياز بـ .items().
- تحققت من الفرق بين الإسناد وcopy() وdeepcopy().
أسئلة شائعة
متى أستعمل التابع بدل القائمة ؟
استعمل التابع لبيانات يجب ألا تتغير (إحداثيات GPS، تاريخ، زوج ثابت). الثبات يحمي من التعديلات العرضية، ويسمح باستعمال التابع كمفتاح قاموس، وهو أسرع قليلا. كل ما يتطور (إضافات وحذف وترتيب) يبقى مجال القائمة.
كيف أجتاز قاموسا ؟
استعمل .items() للحصول على الأزواج : « for cle, valeur in mon_dict.items() ». ويمكنك أيضا اجتياز المفاتيح فقط (.keys()، أو مباشرة for cle in mon_dict) أو القيم (.values()). وللوصول الآمن، فضل .get(cle, defaut) على dict[cle] عندما قد يغيب المفتاح.
ما الفرق بين القائمة والتابع ؟