flowchart TD Collection[<b>الجمع</b> <br> <code>Collection</code>] Collection --> Set[<b>المجموعة</b> <br> <code>Set</code>] Set --> set[<b>المجموعة المتغيرة</b> <br> <code>set</code>] Set --> frozenset[<b>المجموعة الجامدة</b> <br> <code>frozenset</code>]
7 المجموعة
وراجع خريطة المجموعات: شكل 1
المجموعة (set
) هي جمع متغير من عناصر مرقومة فريدة بلا ترتيب.
- متغير: يعني أنها تقبل الإضافة والحذف والتعديل
- مرقومة: هي القابلة للرقم (
hash
) - وسيأتي بيانه - فريدة: يعني أن العنصر لا يتكرر فيها
- بلا ترتيب: فليس للعنصر موضِع (0, 1, 2 …) كما هو الحال في الجمع المرتَّب
أو بالقوسين المتعرجين {}
أو بالإجراء المُنشئ set()
على النحو التالي:
تقبل المجموعة -لكونها من نوع الجمع (Collection)- العمليات التالية:
- العد:
len(s)
- التكرار:
for x in s
- العضوية:
x not in s
وباعتبارها مجموعة متغيرة (MutableSet)، فإنها تقبل الإجراءات التالية:
- الإضافة:
add
- الحذف:
discard
- نزع عنصر عشوائي:
pop
- المحو:
clear
ولا يشترط تجانس العناصر؛ بل يجوز أن تكون أنواعها مختلفة:
ونرى عمليات المجموعة عليها: العد، والعضوية والتكرار:
assert len(s) == 5
assert 'hello' in s
assert 300 not in s
assert (300, 400) in s
for x in s:
print(x)
hello
True
(300, 400)
20
10
وكون المجموعة غير مرتبة، فإنها لا تسجل موقع العنصر أو ترتيب إدراجه. وبالتالي، فإنها لا تقبل الإشارة (xs[i]
) أو التقطيع (xs[i:j]
) أو أي سلوك يشبه المتسلسلات. لاحظ الخطأ التالي:
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) Cell In[4], line 2 1 xs = {10, 20, 30} ----> 2 xs[0] TypeError: 'set' object is not subscriptable
التحقق السريع
عرفنا أن المجموعة تقبل إجراء العضوية x in s
، ولكن ثمة خصوصية لهذا الإجراء في المجموعة. وهذه الخصوصية تكمن في سرعة هذا الإجراء في المجموعة مقارنة بعملة في التسلسل مثلاً:
black_set = {"192.168.1.1", "10.0.0.5", "172.16.0.2"}
ip = "10.0.0.5"
if ip in black_set:
print("Access Denied")
Access Denied
ومثله في التسلسل:
black_list = ["192.168.1.1", "10.0.0.5", "172.16.0.2"]
ip = "10.0.0.5"
if ip in black_list:
print("Access Denied")
Access Denied
لكن الفرق هو تفاصيل هذه العملية، إذ تختلف الكيفية خلف الكواليس. ولن يكون الفرق في السرعة واضحًا إلا حين تكون المجموعة كبيرة جدًّا.
- وذلك أننا في القائمة نحتاج أن نمر على العناصر واحدًا تلو الآخر، حتى نجد العنصر أو لا نجده
- أما في المجموعة، فإن القيمة يتم رقمها (
hash
) حتى يُعرف موقع العنصر في المجموعة مباشرة من غير المرور على عناصرها. فعملية الرقم تعطينا العنوان بشكل ذكي.
إن أردت مزيدًا من التفاصيل فإليك هذا الرابط: https://www.w3schools.com/dsa/dsa_data_hashsets.php.
منطق المجموعة الرياضية
مما تتميز به المجموعة عن بقية أنواع الجمع: قبولها المنطق الرياضي على النحو التالي:
- التقاطع والاتحاد والفرق، والفرق التماثلي
- وكذلك تحقق: (الجزئية والشمول والانفاصل).
وهذه القطعة مثال لجميع هذه العمليات الرياضية:
العمليات على المجموعات
الاتحاد
التقاطع
الفرق
الفرق التماثلي
ملاحظة: لكل من الإجراءات السابقة علامة تمثله كما هو موضَّح في الجدول. إلا أن استعمال اسم الإجراء يقبل أي نوع من المتكررات (Iterables) ولا تقتصر على نوع المجموعة فقط (set
):
العملية | العلامة | الإجراء المكافئ |
---|---|---|
الاتحاد | set1 | set2 |
set1.union(set2) |
التقاطع | set1 & set2 |
set1.intersection(set2) |
الفرق | set1 - set2 |
set1.difference(set2) |
الفرق التماثلي | set1 ^ set2 |
set1.symmetric_difference(set2) |
العلاقات بين المجموعات
الجزئية والشمول
وكذلك لدينا إجراءات تحقق الجزئية والشمول والانفصال:
العملية | العلامة | الإجراء المكافئ |
---|---|---|
تحقق الجزئية | set1 <= set2 |
set1.issubset(set2) |
تحقق الشمول | set1 >= set2 |
set1.issuperset(set2) |
تحقق الانفصال | len(set1 & set2) == 0 |
set1.isdisjoint(set2) |
وهذا مثال لاستعمالها كما في الجدول:
الانفصال
وأما الانفصال، فهو عدم وجود أدنى تقاطع بين المجموعتين: