في بايثون، تعد القواميس واحدة من أكثر أنواع البيانات المضمنة مرونة. فهي رائعة لبناء البيانات ويمكن أن تساعدك في حل عدد لا يحصى من المشكلات. ولكن ماذا لو أخبرتك أن هناك إصدارًا أقوى من القواميس ربما لم تسمع به من قبل؟ نعم، أنا أتحدث عن نوع collections.defaultdict
.
في هذه المقالة، سنستكشف ما هو defaultdict
وكيف يختلف عن قاموس بايثون العادي (أو dict
باختصار).
ما هو اdict؟
القاموس هو نوع بيانات مدمج في بايثون يخزن مجموعات قابلة للتغيير وغير مرتبة من أزواج القيمة والمفتاح. يقوم كل زوج قيمة ومفتاح في القاموس بربط المفتاح بالقيمة المرتبطة به، مما يجعل من السهل استرداد القيم لمفاتيح معينة.
student = {
"name": "John Doe",
"age": 20,
"courses": ["Math", "Science"]
}
print(student["name"])
# Output: John Doe
في هذا الكود، المفاتيح هي “name” و”age” و”courses”، ولكل منها قيم مرتبطة بها. يمكنك الوصول إلى أي قيمة من خلال مفتاحها، كما فعلنا مع student["name"]
.
ولكن ماذا يحدث عندما تحاول الوصول إلى مفتاح غير موجود في القاموس؟ حسنًا، يطرح بايثون خطأ KeyError
:
print(student["grade"])
# Output: KeyError: 'grade'
هذا هو أحد القيود التي تواجه القاموس العادي. فهو لا يتعامل جيدًا مع المفاتيح المفقودة. وفي التطبيقات الواقعية، قد يؤدي هذا إلى تعطل برنامجك إذا لم تكن حريصًا. وهنا يأتي دور defaultdict
s، ولكننا سنتحدث عن ذلك لاحقًا في المقالة.
ملاحظة: يمكنك تجنب استثناءات
KeyError
في القواميس العادية باستخدام التابعget
، والتي تعيد القيمةNone
إذا لم يتم العثور على المفتاح. ومع ذلك، لا يعد هذا مثاليًا دائمًا، وخاصةً عندما تريد توفير قيمة افتراضية بخلافNone
.
ما هو defaultdict؟
defaultdict
هو قاموس متخصص توفره وحدة collections
في بايثون. إنه فئة فرعية من فئة dict
المضمنة. إذن، ما الذي يجعله مميزًا للغاية؟ حسنًا، إنه لا يلقي خطأ KeyError
عندما تحاول الوصول إلى مفاتيح غير موجودة بالفعل في القاموس أو تعديلها. بدلاً من ذلك، يقوم بتهيئته بعنصر من نوع البيانات الذي تمررها كحجة عند إنشاء defaultdict
. يمكن أن يكون هذا مفيدًا للغاية عند العمل مع هياكل بيانات كبيرة.
دعونا نلقي نظرة سريعة على كيفية تهيئة defaultdict
:
from collections import defaultdict
# Initializing with list as default_factory
dd = defaultdict(list)
في المثال أعلاه، إذا حاولت الوصول إلى مفتاح غير موجود، فسوف يقوم بايثون بإرجاع قائمة فارغة []
بدلاً من رمي KeyError
.
print(dd["non_existent_key"])
# Output: []
الحجة التي تمررها أثناء تهيئة defaultdict
تسمى default_factory
. إنها دالة توفر القيمة الافتراضية للقاموس الذي تم إنشاؤه. إذا كانت هذه الحجة غائبة، فإن defaultdict
يتصرف بشكل أساسي مثل القاموس العادي.
الاختلافات الرئيسية
الآن بعد أن فهمنا ما هو defaultdict
، دعنا نلقي نظرة على الاختلافات الرئيسية بين defaultdict
وقاموس بايثون النموذجي.
القيم الافتراضية: الفرق الأكثر أهمية، كما رأينا بالفعل، هو أن defaultdict
يعين تلقائيًا قيمة افتراضية لمفتاح غير موجود. وهذا يختلف عن القاموس القياسي، الذي يثير خطأ KeyError
عند محاولة الوصول إلى مفتاح غير موجود أو تعديله.
# Standard dict
d = {}
print(d["non_existent_key"])
# Output: KeyError: 'non_existent_key'
# Defaultdict
from collections import defaultdict
dd = defaultdict(int)
print(dd["non_existent_key"])
# Output: 0
التهيئة: أثناء تهيئة defaultdict
، تحتاج إلى توفير دالة default_factory
التي ستحدد القيمة الافتراضية للمفاتيح غير الموجودة. من ناحية أخرى، لا يتطلب أو يدعم القاموس القياسي هذه الدالة.
d = {} # Standard dict
dd = defaultdict(list) # Defaultdict
حالات الاستخدام: يعد defaultdict
أكثر فائدة عند التعامل مع مجموعات بيانات كبيرة حيث تريد تجنب التعامل مع استثناءات KeyError
. يُستخدم عادةً في عمليات التجميع أو العد أو التراكم.
متى تستخدم defaultdict مقابل dict
بالطبع، يعتمد الاختيار بين defaultdict
وdict
على احتياجاتك المحددة. إذا كنت تتعامل مع موقف حيث تريد تجنب أخطاء المفاتيح وتعرف مسبقًا نوع القيمة الافتراضية التي تريدها للمفاتيح غير الموجودة، فإن defaultdict
هو الحل.
لنفترض أنك تقوم ببناء قاموس لحساب تكرار الكلمات في نص ما. باستخدام القاموس العادي، يتعين عليك التحقق مما إذا كانت الكلمة مفتاحًا بالفعل في القاموس قبل زيادة عددها. باستخدام defaultdict
، يمكنك ببساطة تعيين نوع القيمة الافتراضية على أنه int وزيادة العدد دون أي فحوصات.
من ناحية أخرى، إذا كنت تريد أن يقوم برنامجك بإلقاء خطأ عند الوصول إلى مفتاح غير موجود، أو إذا لم يكن لديك قيمة افتراضية واضحة، فقد يكون القاموس العادي أكثر ملاءمة.
كيفية استخدام defaultdict
إن استخدام defaultdict
بسيط للغاية. تبدأ باستيراده من وحدة collections
. ثم عندما تقوم بإنشاء defaultdict
، فإنك تمرر النوع الافتراضي للقاموس. قد يكون هذا النوع int
أو list
أو set
أو dict
أو حتى دالة محددة من قبل المستخدم.
دعنا نلقي نظرة على مثال. لنفترض أننا نريد إنشاء قاموس لتخزين درجات الطلاب في مواد مختلفة. يمكننا استخدام defaultdict
مع قائمة كنوع افتراضي:
from collections import defaultdict
# Create a defaultdict with list as the default type
grades = defaultdict(list)
# Add grades
grades['Math'].append(85)
grades['English'].append(90)
print(grades)
عندما تقوم بتشغيل هذا الكود، سوف تحصل على الناتج التالي:
defaultdict(<class 'list'>, {'Math': [85], 'English': [90]})
كما ترى، لم يكن علينا التحقق مما إذا كانت “الرياضيات” أو “اللغة الإنجليزية” من المفاتيح الموجودة بالفعل في القاموس. لقد تمكنا من إضافة الدرجات مباشرة. إذا حاولنا الوصول إلى الدرجات الخاصة بموضوع لم يتم إضافته بعد، فسنحصل على قائمة فارغة بدلاً من خطأ المفتاح:
print(grades['Science'])
سيؤدي هذا إلى:
[]
ملاحظة: تذكر أن النوع الافتراضي الذي تمرر إلى
defaultdict
هو دالة، وليس قيمة. لذا، يجب عليك تمريرlist
بدلاً من[]
، أوint
بدلاً من 0.
كيفية استخدام القاموس
قاموس بايثون هو نوع بيانات مضمّن يستخدم لتخزين البيانات في أزواج مفتاح-قيمة. فيما يلي مثال بسيط لكيفية استخدامه:
# Creating a dictionary
my_dict = {'name': 'John', 'age': 30}
# Accessing a value
print(my_dict['name']) # Output: John
# Updating a value
my_dict['age'] = 31
print(my_dict['age']) # Output: 31
# Adding a new key-value pair
my_dict['job'] = 'Engineer'
print(my_dict) # Output: {'name': 'John', 'age': 31, 'job': 'Engineer'}
أحد الأشياء التي يجب تذكرها عند استخدام dict
هو أنه سيثير KeyError
إذا حاولت الوصول إلى مفتاح غير موجود:
print(my_dict['hobby']) # Raises KeyError: 'hobby'
في هذه المقالة، قمنا بالتعمق أكثر في عالم قواميس بايثون، مع التركيز بشكل خاص على النوعين dict
وcollections.defaultdict
. لقد استكشفنا الاختلافات الرئيسية بينهما، مثل كيفية توفير defaultdict
لقيمة افتراضية للمفاتيح غير الموجودة، وبالتالي تجنب استثناءات KeyError
. لقد نظرنا أيضًا في حالات الاستخدام الخاصة بهما، حيث يكون dict
أفضل للسيناريوهات التي تحتاج فيها إلى التحكم الصارم في المفاتيح الموجودة في القاموس الخاص بك، ويكون defaultdict
أكثر فائدة عندما تتعامل مع مجموعات بيانات كبيرة وتحتاج إلى تجنب عمليات التحقق المستمرة من وجود المفاتيح.
اكتشاف المزيد من بايثون العربي
اشترك للحصول على أحدث التدوينات المرسلة إلى بريدك الإلكتروني.