Python قائمة الانتظار: FIFO، مثال LIFO

⚡ ملخص ذكي

Python الطابور هو بنية بيانات خطية تخزن العناصر وتُحررها بترتيب مُحدد. توفر وحدة الطابور خيارات FIFO وLIFO والأولوية لإدارة المهام وتخزين البيانات مؤقتًا وتنسيق العمل بين الخيوط بأمان.

  • 🔢 FIFO: تقوم فئة Queue بإزالة أقدم عنصر أولاً، وهو أمر مثالي لجدولة المهام والتخزين المؤقت.
  • 🔁 ليفو: تقوم فئة LifoQueue بإزالة أحدث عنصر أولاً، وتتصرف مثل المكدس.
  • 📦 الأساليب الأساسية: تقوم الدوال put() و get() و qsize() و empty() و full() بإدارة العناصر والإبلاغ عن حالة قائمة الانتظار.
  • 🧵 آمن للاستخدام مع الخيوط: تتولى وحدة قائمة الانتظار عملية القفل، لذا يمكن لعدة خيوط مشاركة قائمة انتظار واحدة بأمان.
  • 🎯 الأولوية: تقوم قائمة الانتظار ذات الأولوية بتحرير العناصر حسب الأولوية بدلاً من ترتيب الإدخال.
  • 🤖 مساعدة الذكاء الاصطناعي: تقوم المساعدات المدعومة بالذكاء الاصطناعي بإنشاء رمز قائمة الانتظار وشرح المفاضلات بين FIFO و LIFO من خلال موجه بسيط.

Python ترتيب الطوابير: FIFO LIFO

ما هي تفاصيل Python طابور؟

قائمة الانتظار هي حاوية تحتوي على البيانات. ستتم إزالة البيانات التي تم إدخالها أولاً أولاً، ومن ثم تُسمى قائمة الانتظار أيضًا "الوارد أولاً يخرج أولاً" (FIFO). قائمة الانتظار لها طرفان أمامي وخلفي. يتم إدخال العناصر من الخلف وإزالتها من الجانب الأمامي.

كيف Python العمل في قائمة الانتظار؟

يمكن بسهولة مقارنة قائمة الانتظار بالمثال الواقعي، وهو صف الأشخاص الذين ينتظرون في قائمة الانتظار عند شباك التذاكر، والشخص الذي يقف أولاً سيحصل على التذكرة أولاً، يليه الشخص التالي، وهكذا. ينطبق نفس المنطق على بنية بيانات قائمة الانتظار أيضًا.

فيما يلي تمثيل تخطيطي لقائمة الانتظار:

Python عمل قائمة الانتظار

استخدم خلفي يمثل النقطة التي يتم فيها إدراج العناصر داخل قائمة الانتظار. في هذا المثال، 7 هي القيمة لذلك.

استخدم البوابة الامامية يمثل النقطة التي ستتم فيها إزالة العناصر من قائمة الانتظار. إذا قمت بإزالة عنصر من قائمة الانتظار، فإن العنصر الأول الذي ستحصل عليه هو 1، كما هو موضح في الشكل.

كان العنصر 1 هو أول عنصر يتم إدراجه في قائمة الانتظار، وأثناء إزالته يكون أول عنصر يخرج. ومن هنا تسمى قائمة الانتظار "الوارد أولاً يخرج أولاً" (FIFO)

Python عمل قائمة الانتظار

في قائمة الانتظار، تتم إزالة العناصر بالترتيب ولا يمكن إزالتها من المنتصف. لا يمكنك إزالة العنصر 5 بشكل عشوائي من قائمة الانتظار، للقيام بذلك سيتعين عليك إزالة كافة العناصر قبل العنصر 5. ستتم إزالة العناصر الموجودة في قائمة الانتظار بالترتيب الذي تم إدراجها به.

أنواع قائمة الانتظار في Python

هناك نوعان أساسيان من قائمة الانتظار Python:

  • قائمة انتظار الوارد أولاً يخرج أولاً: لهذا، سيكون العنصر الذي يذهب أولاً هو أول من يخرج. للعمل مع FIFO، عليك الاتصال طابور() فئة من وحدة قائمة الانتظار.
  • قائمة انتظار آخر ما يدخل أولاً: هنا، العنصر الذي تم إدخاله أخيرًا سيكون أول من يخرج. للعمل مع LIFO، عليك الاتصال ليفوكويو() فئة من وحدة قائمة الانتظار.

Python تركيب قائمة الانتظار

من السهل جدًا العمل مع قائمة الانتظار في بايثون. فيما يلي الخطوات التي يجب اتباعها للاستفادة من قائمة الانتظار في التعليمات البرمجية الخاصة بك.

الخطوة 1) كل ما عليك فعله هو استيراد وحدة قائمة الانتظار، كما هو موضح أدناه:

import queue

الوحدة متاحة افتراضيًا مع python، ولا تحتاج إلى أي تثبيت إضافي لبدء العمل مع قائمة الانتظار. هناك نوعان من قائمة الانتظار FIFO (أولاً يخرج أولاً) و LIFO (آخر ما يدخل أولاً يخرج أولاً).

الخطوة 2) للعمل مع قائمة انتظار FIFO، قم باستدعاء فئة Queue باستخدام وحدة قائمة الانتظار المستوردة كما هو موضح أدناه:

import queue
q1 = queue.Queue()

الخطوة 3) للعمل مع قائمة انتظار LIFO، قم باستدعاء فئة LifoQueue() كما هو موضح أدناه:

import queue
q1 = queue.LifoQueue()

الطرق المتاحة داخل فئة Queue وLifoQueue

فيما يلي الطرق الهامة المتوفرة داخل فئة Queue وLifoQueue:

  • وضع (البند): سيؤدي هذا إلى وضع العنصر داخل قائمة الانتظار.
  • يحصل(): سيؤدي هذا إلى إرجاع عنصر من قائمة الانتظار.
  • فارغ(): سيعود صحيحًا إذا كانت قائمة الانتظار فارغة وخطأ إذا كانت العناصر موجودة.
  • حجم (): إرجاع حجم قائمة الانتظار.
  • ممتلىء(): يعود صحيحًا إذا كانت قائمة الانتظار ممتلئة، وإلا يعود خطأ.

مثال على قائمة انتظار الوارد أولاً يخرج أولاً

في حالة ما يدخل أولاً يخرج أولاً، فإن العنصر الذي يذهب أولاً سيكون أول من يخرج.

إضافة وعنصر في قائمة الانتظار

دعونا نعمل على مثال لإضافة عنصر في قائمة الانتظار. لبدء العمل مع قائمة الانتظار، قم أولاً باستيراد قائمة انتظار الوحدة النمطية، كما هو موضح في المثال أدناه.

لإضافة عنصر، يمكنك الاستفادة من طريقة put() كما هو موضح في المثال:

import queue
q1 = queue.Queue()
q1.put(10) #this will additem 10 to the queue.

بشكل افتراضي، يكون حجم قائمة الانتظار لا نهائيًا ويمكنك إضافة أي عدد من العناصر إليها. في حالة رغبتك في تحديد حجم قائمة الانتظار، يمكنك القيام بذلك على النحو التالي

import queue
q1 = queue.Queue(5) #The max size is 5.
q1.put(1)
q1.put(2)
q1.put(3)
q1.put(4)
q1.put(5)
print(q1.full()) # will return true.

الإخراج:

True

الآن أصبح حجم قائمة الانتظار 5، ولن يستغرق الأمر أكثر من 5 عناصر، وسيعود التابع q1.full()‎ صحيحًا. لن تؤدي إضافة المزيد من العناصر إلى تنفيذ التعليمات البرمجية بعد ذلك.

إزالة عنصر من قائمة الانتظار

لإزالة عنصر من قائمة الانتظار، يمكنك استخدام الطريقة المسماة get(). تسمح هذه الطريقة بالعناصر الموجودة في قائمة الانتظار عند استدعائها.

يوضح المثال التالي كيفية إزالة عنصر من قائمة الانتظار.

import queue
q1 = queue.Queue()
q1.put(10)

item1 = q1.get()

print('The item removed from the queue is ', item1)

الإخراج:

The item removed from the queue is  10

مثال على قائمة انتظار ما يدخل أولاً يخرج أولاً

في حالة وجود العنصر الأخير في قائمة انتظار الخروج الأول، سيكون العنصر الذي تم إدخاله أخيرًا هو أول العنصر الذي يخرج.

للعمل مع LIFO، أي الأخير في قائمة انتظار الخروج الأول، نحتاج إلى استيراد وحدة قائمة الانتظار والاستفادة من طريقة LifoQueue().

إضافة وعنصر في قائمة الانتظار

سوف نفهم هنا كيفية إضافة عنصر إلى قائمة انتظار LIFO.

import queue
q1 = queue.LifoQueue()
q1.put(10)

يجب عليك استخدام طريقة put() على LifoQueue، كما هو موضح في المثال أعلاه.

إزالة عنصر من قائمة الانتظار

لإزالة عنصر من قائمة LIFOqueue، يمكنك الاستفادة من طريقة get() .

import queue
q1 = queue.LifoQueue()
q1.put(10)

item1 = q1.get()

print('The item removed from the LIFO queue is ', item1)

الإخراج:

The item removed from the LIFO queue is  10

إضافة أكثر من عنصر واحد في قائمة الانتظار

في الأمثلة المذكورة أعلاه، رأينا كيفية إضافة عنصر واحد وإزالة العنصر لـ FIFO وLIFOqueue. سنرى الآن كيفية إضافة أكثر من عنصر وإزالته أيضًا.

إضافة وعنصر في قائمة انتظار FIFO

import queue
q1 = queue.Queue()

for i in range(20):
    q1.put(i) # this will additem from 0 to 20 to the queue

إزالة عنصر من قائمة انتظار FIFO

import queue
q1 = queue.Queue()

for i in range(20):
    q1.put(i) # this will additem from 0 to 20 to the queue

while not q1.empty():
print("The value is ", q1.get()) # get() will remove the item from the queue.

الإخراج:

The value is  0
The value is  1
The value is  2
The value is  3
The value is  4
The value is  5
The value is  6
The value is  7
The value is  8
The value is  9
The value is  10
The value is  11
The value is  12
The value is  13
The value is  14
The value is  15
The value is  16
The value is  17
The value is  18
The value is  19

إضافة وعنصر في قائمة انتظار LIFO

import queue
q1 = queue.LifoQueue()
for i in range(20):
    q1.put(i) # this will additem from 0 to 20 to the queue

قم بإزالة عنصر من قائمة LIFOqueue

import queue
q1 = queue.LifoQueue()

for i in range(20):
    q1.put(i) # this will additem from 0 to 20 to the queue

while not q1.empty():
print("The value is ", q1.get()) # get() will remove the item from the queue.

الإخراج:

The value is  19
The value is  18
The value is  17
The value is  16
The value is  15
The value is  14
The value is  13
The value is  12
The value is  11
The value is  10
The value is  9
The value is  8
The value is  7
The value is  6
The value is  5
The value is  4
The value is  3
The value is  2
The value is  1
The value is  0 

فرز قائمة الانتظار

يوضح المثال التالي فرز قائمة الانتظار. الخوارزمية المستخدمة للفرز هي فرز الفقاعات.

import queue
q1 = queue.Queue()
#Addingitems to the queue
q1.put(11)
q1.put(5)
q1.put(4)
q1.put(21)
q1.put(3)
q1.put(10)

#using bubble sort on the queue
n =  q1.qsize()
for i in range(n):
    x = q1.get() # the element is removed
    for j in range(n-1):
        y = q1.get() # the element is removed
        if x > y :  
            q1.put(y)   #the smaller one is put at the start of the queue
        else:
            q1.put(x)  # the smaller one is put at the start of the queue
            x = y     # the greater one is replaced with x and compared again with nextelement
    q1.put(x)

while (q1.empty() == False): 
print(q1.queue[0], end = " ")  
        q1.get()

الإخراج:

3 4 5 10 11 21

Revقائمة الانتظار

لعكس قائمة الانتظار، يمكنك الاستفادة من قائمة انتظار أخرى وتكرار.

يوضح المثال التالي كيفية عكس قائمة الانتظار.

على سبيل المثال:

import queue
q1 = queue.Queue()

q1.put(11)
q1.put(5)
q1.put(4)
q1.put(21)
q1.put(3)
q1.put(10)

def reverseQueue (q1src, q2dest) :  
    buffer = q1src.get()
    if (q1src.empty() == False) :
reverseQueue(q1src, q2dest)      #using recursion
    q2dest.put(buffer)
return q2dest

q2dest = queue.Queue()
qReversed = reverseQueue(q1,q2dest)

while (qReversed.empty() == False): 
print(qReversed.queue[0], end = " ")  
        qReversed.get()

الإخراج:

10 3 21 4 5 11

الأسئلة الشائعة

الطابور هو FIFO، لذا يغادر العنصر الأقدم أولاً، بينما المكدس هو LIFO، حيث يغادر العنصر الأحدث أولاً. Pythonتوفر وحدة قائمة الانتظار الخاصة بـ 's قائمة انتظار لسلوك FIFO و LifoQueue لسلوك المكدس.

نعم. تم تصميم Queue و LifoQueue و PriorityQueue للبرامج متعددة الخيوط وتتعامل مع التأمين داخليًا، لذلك يمكن للعديد من خيوط المنتج والمستهلك مشاركة قائمة انتظار واحدة دون حدوث حالات تنافس أو تلف في البيانات.

تُعدّ queue.Queue آمنة للاستخدام في بيئات متعددة الخيوط ومصممة خصيصًا لبرامج المنتج والمستهلك. أما collections.deque فهي طابور ثنائي الأطراف أسرع وأعمّال الاستخدام، مصمم للبرامج أحادية الخيوط، ويدعم عمليات الإضافة والحذف السريعة من كلا الطرفين.

تقوم قائمة الانتظار ذات الأولوية بتحرير العناصر حسب ترتيب الأولوية بدلاً من ترتيب الإدخال. يتم وضع أزواج (الأولوية، البيانات)، وتعيد الدالة get() رقم الأولوية الأدنى أولاً، وهو ما يناسب المجدولات وخوارزميات أقصر مسار.

بشكل افتراضي، تقوم الدالة get() بحظر التنفيذ وتنتظر حتى يصبح العنصر متاحًا. مرر قيمة block=False أو استخدم الدالة get_nowait() لإثارة استثناء queue.Empty فورًا بدلًا من انتظار عنصر جديد.

مرر قيمة maxsize إلى الدالة البانية، على سبيل المثال queue.Queue(5). عندما تمتلئ قائمة الانتظار، تتوقف الدالة put() مؤقتًا حتى تتوفر مساحة، ثم تُرجع الدالة full() القيمة True. قيمة maxsize تساوي 0 تعني قائمة انتظار غير محدودة.

تُنشئ المساعدات المدعومة بالذكاء الاصطناعي شيفرة طابور المنتج والمستهلك، وتشرح المفاضلات بين FIFO وLIFO، وتقترح ما إذا كان queue.Queue أو deque أو asyncio.Queue مناسبًا لحالتك. كما أنها تساعد في اكتشاف حالات التعطل وعدم استدعاء task_done().

نعم. يُكمل GitHub Copilot تلقائيًا إعدادات قائمة الانتظار، وحلقات put() و get()، وخيوط العمل من تعليق. وتذهب أدوات الذكاء الاصطناعي الوكيل إلى أبعد من ذلك، حيث تُعيد هيكلة التعليمات البرمجية المُعطِّلة إلى asyncio.Queue وتُضيف معالجة الأخطاء عبر الملف.

تلخيص هذه التدوينة بـ: