This post is also available in: English (الإنجليزية)
تم استخدام Python في جميع أنحاء العالم في مجالات مختلفة مثل إنشاء مواقع الويب والذكاء الاصطناعي وغير ذلك الكثير. ولكن لجعل كل هذا ممكنًا ، تلعب البيانات دورًا مهمًا للغاية مما يعني أنه يجب تخزين هذه البيانات بكفاءة ويجب أن يكون الوصول إليها في الوقت المناسب. فكيف تحقق هذا؟ نحن نستخدم شيئًا يسمى هياكل البيانات.
ما هي بنية البيانات؟
هيكل البيانات هو تنسيق متخصص لتنظيم ومعالجة واسترجاع وتخزين البيانات. تُستخدم أنواع مختلفة من هياكل البيانات في لغات برمجة مختلفة ، وكلها مصممة لترتيب البيانات لتناسب غرضًا معينًا. تجعل هياكل البيانات من السهل على المستخدمين الوصول إلى البيانات التي يحتاجونها والعمل معها بطرق مناسبة.
في علوم الكمبيوتر وبرمجة الكمبيوتر ، يمكن اختيار بنية بيانات أو تصميمها لتخزين البيانات بغرض استخدامها مع خوارزميات مختلفة.
أنواع هياكل البيانات في بايثون
تقدم Python نوعين من هياكل البيانات:
- هياكل البيانات المدمجة
- هياكل البيانات المعرفة من قبل المستخدم
Data Structures in Python
هياكل البيانات المدمجة
كما يوحي الاسم ، فإن هياكل البيانات هذه مدمجة في Python مما يجعل البرمجة أسهل ويساعد المبرمجين على استخدامها للحصول على الحلول بشكل أسرع.
فيما يلي هياكل البيانات المضمنة في Python:
- قائمة
- قاموس
- توبلي
- جلس
1. قائمة
تُستخدم القوائم لتخزين البيانات من أنواع البيانات المختلفة بترتيب تسلسلي. هناك عناوين مخصصة لكل عنصر من عناصر القائمة ، وهو ما يسمى الفهرس. تبدأ قيمة الفهرس من 0 وتستمر حتى العنصر الأخير. يُسمح بالفهرسة السلبية التي تبدأ من -1 مما يتيح لك الوصول إلى العناصر من الأخير إلى الأول.
دعونا نفهم العمليات المختلفة في القوائم:
إنشاء قائمة
لإنشاء قائمة ، يمكنك استخدام الأقواس المربعة وإضافة عناصر إليها وفقًا لذلك. إذا لم تمرر أي عناصر داخل الأقواس المربعة ، فستحصل على قائمة فارغة كإخراج.
my_list = [] #create empty listprint(my_list)my_list = [1, 2, 3, ‘example’, 3.132] #creating list with dataprint(my_list)
انتاج:
[]
[1, 2, 3, ‘example’, 3.132]
إدراج عنصر في قائمة
يمكن إدراج العناصر في قائمة باستخدام الدالات append () و extension () و insert ().
- تضيف الدالة append() جميع العناصر التي تم تمريرها إليها كعنصر واحد.
- تضيف الدالة extend() العناصر واحدًا تلو الآخر إلى القائمة.
- تضيف وظيفة insert () العنصر الذي تم تمريره إلى قيمة الفهرس وتزيد من حجم القائمة أيضًا.
my_list = [1, 2, 3]print(my_list)my_list.append([555, 12]) #add as a single elementprint(my_list)my_list.extend([234, ‘more_example’]) #add as different elementsprint(my_list)my_list.insert(1, ‘insert_example’) #add element iprint(my_list)
انتاج:
[1, 2, 3]
[1, 2, 3, [555, 12]]
[1, 2, 3, [555, 12], 234, ‘more_example’]
[1, ‘insert_example’, 2, 3, [555, 12], 234, ‘more_example’]
حذف عنصر من قائمة
يمكن حذف العناصر من قائمة باستخدام الكلمات الأساسية del ، و function pop () و remove ().
- لحذف العناصر ، استخدم الكلمة الأساسية del المضمنة في Python ولكن هذا لا يعيد أي شيء إلينا.
- إذا كنت تريد عودة العنصر ، يمكنك استخدام وظيفة pop () التي تأخذ قيمة الفهرس.
- لإزالة عنصر بقيمته ، يمكنك استخدام وظيفة remove ().
my_list = [1, 2, 3, ‘example’, 3.132, 10, 30]del my_list[5] #delete element at index 5print(my_list)my_list.remove(‘example’) #remove element with valueprint(my_list)a = my_list.pop(1) #pop element from listprint(‘Popped Element: ‘, a, ‘ List remaining: ‘, my_list)my_list.clear() #empty the listprint(my_list)
انتاج:
[1, 2, 3, ‘example’, 3.132, 30]
[1, 2, 3, 3.132, 30]
العنصر المنبثق: 2 القائمة المتبقية: 1 ، 3 ، 3.132 ، 30]
[]
الوصول إلى عناصر القائمة
الوصول إلى العناصر هو نفس الوصول إلى Stringsفي Python. يمكنك تمرير قيم الفهرس وبالتالي يمكنك الحصول على القيم حسب الحاجة.
my_list = [1, 2, 3, ‘example’, 3.132, 10, 30]for element in my_list: #access elements one by one print(element)print(my_list) #access all elementsprint(my_list[3]) #access index 3 elementprint(my_list[0:2]) #access elements from 0 to 1 and exclude 2print(my_list[::-1]) #access elements in reverse
انتاج:
1
2
3
example
3.132
10
30
[1, 2, 3, ‘example’, 3.132, 10, 30]
example
[1. 2]
[30, 10, 3.132, ‘example’, 3, 2, 1]
وظائف أخرى
- الدالة len() ترجع إلينا طول القائمة.
- تعثر الدالة index() على قيمة الفهرس للقيمة التي تم تمريرها حيث تمت مواجهتها في المرة الأولى.
- تبحث الدالة count() عن عدد القيمة التي تم تمريرها إليها.
- تعمل الدالتان Sorted() و sort() على فرز قيم القائمة. الفرز () له نوع إرجاع بينما يقوم sort () بتعديل القائمة الأصلية.
my_list = [1, 2, 3, 10, 30, 10]print(len(my_list)) #find length of listprint(my_list.index(10)) #find index of element that occurs firstprint(my_list.count(10)) #find count of the elementprint(sorted(my_list)) #print sorted list but not change originalmy_list.sort(reverse=True) #sort original listprint(my_list)
انتاج:
6
3
2
[1, 2, 3, 10, 10, 30]
[30, 10, 10, 3, 2, 1]
2. القاموس
تُستخدم القواميس لتخزين أزواج المفتاح والقيمة. يمكن اعتبار القاموس كدليل هاتف يحتوي على مئات وآلاف من الأسماء والأرقام المقابلة لها. هنا تسمى القيم الثابتة Name وأرقام الهاتف بالمفاتيح. الأسماء المختلفة وأرقام الهواتف هي القيم التي تم إدخالها إلى المفاتيح. إذا قمت بالوصول إلى قيم المفاتيح ، فستحصل على جميع الأسماء وأرقام الهواتف. إذن هذا هو زوج القيمة الرئيسية. في Python ، يتم تخزين هذه البنية باستخدام القواميس.
إنشاء قاموس
يمكن إنشاء القواميس باستخدام الأقواس المعقوفة أو باستخدام وظيفة dict(). تحتاج إلى إضافة أزواج المفتاح والقيمة كلما عملت مع القواميس.
my_dict = {} #empty dictionaryprint(my_dict)my_dict = {1: ‘Python’, 2: ‘Java’} #dictionary with elementsprint(my_dict)
انتاج:
{}
{1: ‘Python’, 2: ‘Java’}
تغيير وإضافة أزواج المفتاح والقيمة
لتغيير قيم القاموس ، عليك القيام بذلك باستخدام المفاتيح. لذلك ، يمكنك الوصول إلى المفتاح أولاً ثم تغيير القيمة وفقًا لذلك. لإضافة قيم ، ما عليك سوى إضافة زوج قيم مفتاح آخر كما هو موضح أدناه:
my_dict = {‘First’: ‘Python’, ‘Second’: ‘Java’}print(my_dict)my_dict[‘Second’] = ‘C++’ #changing elementprint(my_dict)my_dict[‘Third’] = ‘Ruby’ #adding key-value pairprint(my_dict)
انتاج:
{‘First’: ‘Python’, ‘Second’: ‘Java’}
{‘First’: ‘Python’, ‘Second’: ‘C++’}
{‘First’: ‘Python’, ‘Second’: ‘C++’, ‘Third’: ‘Ruby’}
حذف أزواج المفتاح والقيمة
يمكن حذف العناصر من القاموس باستخدام الدالات pop () و popitem () و clear ().
- لحذف القيم ، يمكنك استخدام وظيفة pop() التي تُرجع القيمة التي تم حذفها.
- لاسترداد زوج المفتاح والقيمة ، يمكنك استخدام وظيفة popitem() ، التي تُرجع مفتاحًا وقيمة tuple.
- لمسح القاموس بالكامل ، يمكنك استخدام وظيفة clear().
my_dict = {‘First’: ‘Python’, ‘Second’: ‘Java’, ‘Third’: ‘Ruby’}a = my_dict.pop(‘Third’) #pop elementprint(‘Value:’, a)print(‘Dictionary:’, my_dict)b = my_dict.popitem() #pop the key-value pairprint(‘Key, value pair:’, b)print(‘Dictionary’, my_dict)my_dict.clear() #empty dictionaryprint(‘n’, my_dict)
انتاج:
Value: Ruby
Dictionary: {‘First’: ‘Python’, ‘Second’: ‘Java’}
Key, value pair: (‘Second’, ‘Java’)
Dictionary {‘First’: ‘Python’}
{}
الوصول إلى العناصر
يمكنك الوصول إلى العناصر باستخدام المفاتيح فقط. يمكنك استخدام وظيفة get() أو تمرير قيم المفاتيح فقط وستتمكن من استرداد القيم.
my_dict = {‘First’: ‘Python’, ‘Second’: ‘Java’}print(my_dict[‘First’]) #access elements using keysprint(my_dict.get(‘Second’))
انتاج:
Python
Java
وظائف أخرى
بصرف النظر عن هذه العمليات الأساسية ، هناك عدد قليل من الوظائف الأخرى لأداء مهام محددة. هؤلاء هم:
- Keys(): تقوم بإرجاع المفتاح.
- values(): تُستخدم لإرجاع القيمة.
- items(): تقوم بإرجاع زوج المفتاح والقيمة.
my_dict = {‘First’: ‘Python’, ‘Second’: ‘Java’, ‘Third’: ‘Ruby’}print(my_dict.keys()) #get keysprint(my_dict.values()) #get valuesprint(my_dict.items()) #get key-value pairsprint(my_dict.get(‘First’))
انتاج:
dict_keys([‘First’, ‘Second’, ‘Third’])
dict_values([‘Python’, ‘Java’, ‘Ruby’])
dict_items([(‘First’, ‘Python’), (‘Second’, ‘Java’), (‘Third’, ‘Ruby’)])
Python
3. Tuple
تتشابه المجموعات مع القوائم فيما عدا أن البيانات التي تم إدخالها مرة واحدة في المجموعة لا يمكن تغييرها تحت أي ظرف من الظروف. الاستثناء الوحيد هو عندما تكون البيانات داخل المجموعة قابلة للتغيير. سيساعدك المثال التالي على الفهم.
إنشاء Tuple
يمكنك إنشاء مجموعة باستخدام الأقواس أو باستخدام وظيفة tuple().
my_tuple = (1, 2, 3) #create tuplet2 = tuple([1, 4, 6])print(my_tuple)print(t2)
انتاج:
(1, 2, 3)
(1, 4, 6)
الوصول إلى العناصر
الوصول إلى العناصر هو نفسه للوصول إلى القيم في القوائم.
my_tuple2 = (1, 2, 3, ‘phyton’) #access elementsfor x in my_tuple2: print(x)print(my_tuple2)print(my_tuple2[0])print(my_tuple2[:])print(my_tuple2[3][4])
انتاج:
1
2
3
python
(1, 2, 3, ‘python’)
1
(1, 2, 3, ‘python’)
o
إلحاق العناصر
لإلحاق القيم ، يمكنك استخدام عامل التشغيل “+” الذي سيأخذ مجموعة أخرى ليتم إلحاقها به.
my_tuple = (1, 2, 3)my_tuple = my_tuple + (4, 5, 6) #add elementsprint(my_tuple)
انتاج:
(1, 2, 3, 4, 5, 6)
وظائف أخرى
بصرف النظر عن هذه العمليات الأساسية ، هناك عدد قليل من الوظائف الأخرى لأداء مهام محددة. يوضح المثال التالي هذه الوظائف.
my_tuple = (1, 2, 3, [‘hindi’, ‘python’])my_tuple[3][0] = ‘english’print(my_tuple)print(my_tuple.count(2))print(my_tuple.index([‘english’, ‘python’]))
انتاج:
(1, 2, 3, [‘english’], [‘python’])
1
3
4. مجموعة
المجموعات هي مجموعة من العناصر غير المرتبة الفريدة. وهذا يعني أنه حتى إذا تكررت البيانات أكثر من مرة ، فسيتم إدخالها في المجموعة مرة واحدة فقط. إنها تشبه المجموعاتالتي تعلمتها في الرياضيات. العمليات هي نفسها كما في الرياضيات.
خلق مجموعة
يتم إنشاء المجموعات باستخدام الأقواس المتعرجة ولكن بدلاً من إضافة أزواج من المفاتيح والقيمة ، تقوم فقط بتمرير القيم إليها.
my_set = {1, 2, 3, 4, 5, 5, 5} #create setprint(my_set)
انتاج:
{1, 2, 3, 4, 5}
مضيفا العناصر
لإضافة عناصر ، يمكنك استخدام الوظيفة add() وتمرير القيمة إليها.
my_set = {1, 2, 3}my_set.add(4) #add element to setprint(my_set)
انتاج:
{1, 2, 3, 4}
العمليات في مجموعات
- تجمع الدالة union() بين البيانات الموجودة في كلا المجموعتين.
- تعثر دالة intersection() على البيانات الشائعة الموجودة في كلا المجموعتين.
- تعمل وظيفة difference() على حذف البيانات الموجودة في كلاهما وإخراج البيانات الموجودة فقط في المجموعة التي تم تمريرها.
- تقوم symmetric_difference () بنفس وظيفة difference() ولكنها تنتج البيانات المتبقية في كلا المجموعتين.
يوضح المثال التالي العمليات في مجموعة.
my_set = {1, 2, 3, 4}my_set_2 = {3, 4, 5, 6}print(my_set.union(my_set_2), ‘———-‘, my_set | my_set_2)print(my_set.intersection(my_set_2), ‘———-‘, my_set & my_set_2)print(my_set.difference(my_set_2), ‘———-‘, my_set – my_set_2)print(my_set.symmetric_difference(my_set_2), ‘———-‘, my_set ^ my_set_2)my_set.clear()print(my_set)
انتاج:
{1, 2, 3, 4, 5, 6} —————– {1, 2, 3, 4, 5, 6}
{3, 4} ————— {3, 4}
{1, 2} ————— {1, 2}
{1, 2, 5, 6} ————— {1, 2, 5, 6}
set()
هياكل البيانات المعرفة من قبل المستخدم
هذه هي هياكل البيانات التي لا تدعمها Python ولكن يمكن برمجتها لتعكس نفس الوظيفة باستخدام المفاهيم التي تدعمها Python.
1. كومة
الأكوام عبارة عن هياكل بيانات خطية تستند إلى مبدأ Last-In-First-Out (LIFO) حيث ستكون البيانات التي تم إدخالها مؤخرًا هي أول من يتم الوصول إليه. تم بناؤه باستخدام بنية المصفوفة وله عمليتان. اضغط (إضافة عنصر) العناصر وانبثق (حذف العنصر) والوصول إلى العناصر من أحد طرفي استدعاء المكدس مثل TOP. هذا الجزء العلوي هو المؤشر إلى الموضع الحالي للمكدس. تُستخدم الحزم بشكل بارز في تطبيقات مثل البرمجة التكرارية ، وعكس الكلمات ، وآليات التراجع في محررات الكلمات ، وما إلى ذلك.
stack = [‘first’, ‘second’, ‘third’]print(stack)print()# pushing elementsstack.append(‘fourth’)stack.append(‘fifth’)print(stack)print()# printing topn = len(stack)print(stack[n-1])print()# poping elementstack.pop()print(stack)
انتاج:
[‘first’, ‘second’, ‘third’]
[‘first’, ‘second’, ‘third’, ‘fourth’, ‘fifth’]
fifth
[‘first’, ‘second’, ‘third’, ‘fourth’]
2. قائمة الانتظار
قائمة الانتظار هي بنية بيانات خطية تسمح بإدخال العناصر من أحد الطرفين (يسمى REAR) والحذف من الطرف الآخر (يسمى FRONT). وبالتالي فهي تتبع منهجية الوارد أولاً يصرف أولاً (FIFO).
queue = [‘first’, ‘second’, ‘third’]print(queue)print()# pushing elementsqueue.append(‘fourth’)queue.append(‘fifth’)print(queue)print()# printing headprint(queue[0])# printing tailn = len(queue)print(queue[n-1])print()# poping elementqueue.remove(queue[0])print(queue)
انتاج |
[‘first’, ‘second’, ‘third’]
[‘first’, ‘second’, ‘third’, ‘fourth’, ‘fifth’]
first
fifth
[‘second’, ‘third’, ‘fourth’, ‘fifth’]
3. شجرة
الشجرة هي بنية بيانات غير خطية ولكنها هرمية. يُعرف العنصر الأعلى باسم جذرالشجرة حيث يُعتقد أنه يبدأ من الجذر. تُعرف العناصر الموجودة في نهاية الشجرة بأوراقها (ورقة مفردة). تعتبر الأشجار مناسبة لتخزين البيانات غير المرتبطة ببعضها البعض خطيًا ولكنها تشكل تسلسلاً هرميًا.
class node:def __init__(self, ele):self.ele = eleself.left = Noneself.right = Nonedef preorder(self):if self:print(self.ele)preorder(self.left)preorder(self.right)n = node(‘first’)n.left = node(‘second’)n.right = node(‘third’)preorder(n)
يمكنك رؤية اجتياز الشجرة هنا.
انتاج:
first
second
third
4. قائمة مرتبطة
القائمةالمرتبطة هي بنية بيانات خطية ، حيث لا يتم تخزين العناصر في مواقع ذاكرة متجاورة. ترتبط العناصر الموجودة في قائمة مرتبطة باستخدام المؤشرات كما هو موضح في الصورة أدناه:
llist = [‘first’, ‘second’, ‘third’]print(llist)print()# adding elementsllist.append(‘fourth’)llist.append(‘fifth’)llist.insert(3, ‘sixth’)print(llist)print()llist.remove(‘second’)print(llist)print()
انتاج:
[‘first’, ‘second’, ‘third’]
[‘first’, ‘second’, ‘third’, ‘sixth’, ‘fourth’, ‘fifth’]
[‘first’, ‘third’, ‘sixth’, ‘fourth’, ‘fifth’]
5. الرسم البياني
الرسم البياني هو بنية بيانات غير خطية تتكون من عقد وحواف. يشار إلى العقد أحيانًا بالرؤوس والحواف عبارة عن خطوط أو أقواس تربط أي عقدتين في الرسم البياني. يتكون الرسم البياني من مجموعة محدودة من الرؤوس (أو العقد) والحواف التي تربط زوجًا من العقد.
class adjnode:def __init__(self, val):self.val = valself.next = Noneclass graph:def __init__(self, vertices):self.v = verticesself.ele = [None]*self.vdef edge(self, src, dest):node = adjnode(dest)node.next = self.ele[src]self.ele[src] = nodenode = adjnode(src)node.next = self.ele[dest]self.ele[dest] = nodedef __repr__(self):for i in range(self.v):print(“Adjacency list of vertex {}n head”.format(i), end=””)temp = self.ele[i]while temp:print(” -> {}”.format(temp.val), end=””)temp = temp.nextg = graph(4)g.edge(0, 2)g.edge(1, 3)g.edge(3, 2)g.edge(0, 3)g.__repr__()
انتاج:
قائمة تجاور قمة الرأس 0
head -> 3 -> 2
قائمة تجاور قمة الرأس 1
head -> 3
قائمة تجاور قمة الرأس 2
head -> 3 -> 0
قائمة تجاور قمة الرأس 3
head -> 0 -> 2 -> 1
6. خريطة تجزئة
Hashmaps هي هياكل بيانات مفهرسة. يستخدم hashmap وظيفة التجزئة لحساب فهرس بمفتاح في مجموعة من المجموعات أو الفتحات. يتم تعيين قيمته إلى الحاوية مع الفهرس المقابل. المفتاح فريد وغير قابل للتغيير. في لغة بايثون ، تعتبر القواميس أمثلة على علامات التجزئة.
def printdict(d):for key in d:print(key, “->”, d[key])hm = {0: ‘first’, 1: ‘second’, 2: ‘third’}printdict(hm)print()hm[3] = ‘fourth’printdict(hm)print()hm.popitem()printdict(hm)
انتاج:
0 -> first
1 -> second
2 -> third
0 -> first
1 -> second
2 -> third
3 -> fourth
0 -> first
1 -> second
2 -> third