คำแนะนำเกี่ยวกับคิวใน Python

คำแนะนำเกี่ยวกับคิวใน Python

บทนำ

ตั้งแต่การจัดเก็บจำนวนเต็มอย่างง่ายไปจนถึงการจัดการเวิร์กโฟลว์ที่ซับซ้อน โครงสร้างข้อมูลเป็นรากฐานสำหรับแอปพลิเคชันที่แข็งแกร่ง ในหมู่พวกเขา คิว มักจะปรากฏให้เห็นทั้งที่น่าสนใจและแพร่หลาย ลองคิดดูสิ - ก สายที่ธนาคารรอถึงคิวที่เคาน์เตอร์ฟาสต์ฟู้ด หรือบัฟเฟอร์งานในระบบคอมพิวเตอร์ สถานการณ์ทั้งหมดนี้สอดคล้องกับกลไกของคิว

คนแรกที่เข้าแถวจะได้รับบริการก่อน และผู้มาใหม่จะเข้าร่วมในตอนท้าย นี่คือตัวอย่างการใช้งานจริงของคิว!

คู่มือคิวในหลาม-01.png

สำหรับนักพัฒนา โดยเฉพาะใน Python คิวไม่ได้เป็นเพียงโครงสร้างทางทฤษฎีจากหนังสือเรียนวิทยาการคอมพิวเตอร์เท่านั้น พวกมันสร้างสถาปัตยกรรมพื้นฐานในแอปพลิเคชั่นมากมาย ตั้งแต่การจัดการงานในเครื่องพิมพ์ไปจนถึงการสตรีมข้อมูลได้อย่างราบรื่นในการถ่ายทอดสด คิวมีบทบาทที่ขาดไม่ได้

ในคู่มือนี้ เราจะเจาะลึกแนวคิดของคิว สำรวจคุณลักษณะ แอปพลิเคชันในโลกแห่งความเป็นจริง และที่สำคัญที่สุดคือวิธีนำไปใช้และใช้งานคิวใน Python อย่างมีประสิทธิภาพ

โครงสร้างข้อมูลคิวคืออะไร?

เมื่อสำรวจภูมิทัศน์ของโครงสร้างข้อมูลแล้ว เรามักจะพบคอนเทนเนอร์ที่มีกฎเกณฑ์ที่แตกต่างกันสำหรับการป้อนและเรียกข้อมูล ในจำนวนนี้ คิว โดดเด่นด้วยความสง่างามและความตรงไปตรงมา

หลักการ FIFO

ที่แกนหลัก คิวคือโครงสร้างข้อมูลเชิงเส้นที่ยึดตาม เข้าก่อนออกก่อน (FIFO) หลักการ. ซึ่งหมายความว่าองค์ประกอบแรกที่เพิ่มลงในคิวจะเป็นองค์ประกอบแรกที่จะถูกลบออก หากต้องการเปรียบเสมือนสถานการณ์ที่เกี่ยวข้อง: ลองพิจารณาต่อคิวลูกค้าที่เคาน์เตอร์จำหน่ายตั๋ว ผู้ที่มาถึงก่อนจะได้รับตั๋วก่อน และผู้มาถึงต่อๆ ไปจะเข้าแถวในตอนท้ายเพื่อรอถึงตาพวกเขา

หมายเหตุ คิวมีสองปลาย - ด้านหลังและด้านหน้า. ด้านหน้าบ่งบอกว่าองค์ประกอบต่างๆ จะถูกลบออกจากที่ใด และด้านหลังบ่งบอกว่าองค์ประกอบใหม่ๆ จะถูกเพิ่มไปที่ใด

การดำเนินการคิวขั้นพื้นฐาน

  • เข้าคิว – การกระทำของ เพิ่ม องค์ประกอบจนถึงจุดสิ้นสุด (ด้านหลัง) ของคิว

    คู่มือคิวในหลาม-02.png

  • คิว – การกระทำของ ลบ องค์ประกอบจาก ด้านหน้า ของคิว

    คู่มือคิวในหลาม-03.png

  • มองหรือด้านหน้า – ในหลาย ๆ สถานการณ์ แค่สังเกตองค์ประกอบด้านหน้าโดยไม่ต้องถอดออกก็มีประโยชน์ การดำเนินการนี้ช่วยให้เราสามารถทำเช่นนั้นได้

  • มันว่างเปล่า – การดำเนินการที่ช่วยพิจารณาว่าคิวมีองค์ประกอบใดๆ หรือไม่ นี่อาจมีความสำคัญในสถานการณ์ที่การดำเนินการเกิดขึ้นกับคิวที่มีข้อมูล

หมายเหตุ แม้ว่าบางคิวจะมีขนาดที่จำกัด (คิวแบบมีขอบเขต) แต่บางคิวก็สามารถขยายได้ตราบใดที่หน่วยความจำระบบอนุญาต (คิวแบบไม่มีขอบเขต)

ความเรียบง่ายของคิวและกฎการดำเนินการที่ชัดเจน ทำให้คิวเหล่านี้เหมาะสำหรับแอปพลิเคชันต่างๆ ในการพัฒนาซอฟต์แวร์ โดยเฉพาะอย่างยิ่งในสถานการณ์ที่ต้องการการประมวลผลที่เป็นระเบียบและเป็นระบบ

อย่างไรก็ตาม การทำความเข้าใจทฤษฎีนี้เป็นเพียงก้าวแรกเท่านั้น เมื่อเราก้าวไปข้างหน้า เราจะเจาะลึกแง่มุมเชิงปฏิบัติ ซึ่งแสดงให้เห็นวิธีการนำคิวไปใช้ใน Python

วิธีการใช้คิวใน Python – รายการกับ Deque กับโมดูลคิว

Python ซึ่งมีไลบรารีมาตรฐานที่หลากหลายและไวยากรณ์ที่ใช้งานง่าย มีกลไกหลายอย่างในการนำไปใช้และทำงานกับคิว แม้ว่าทั้งหมดจะตอบสนองวัตถุประสงค์พื้นฐานของการจัดการคิว แต่ก็มาพร้อมกับความแตกต่าง ข้อดี และข้อผิดพลาดที่อาจเกิดขึ้น เรามาวิเคราะห์แต่ละแนวทางกัน โดยแสดงกลไกและกรณีการใช้งานที่ดีที่สุด

หมายเหตุ ตรวจสอบสถานะคิวของคุณก่อนดำเนินการทุกครั้ง ตัวอย่างเช่น ก่อนที่จะถอนคิว ให้ตรวจสอบว่าคิวว่างหรือไม่เพื่อหลีกเลี่ยงข้อผิดพลาด ในทำนองเดียวกัน สำหรับคิวที่มีขอบเขต ตรวจสอบให้แน่ใจว่ามีพื้นที่ว่างก่อนที่จะเข้าคิว

การใช้รายการ Python เพื่อนำคิวไปใช้

การใช้รายการในตัวของ Python เพื่อนำคิวไปใช้นั้นทำได้ง่ายและตรงไปตรงมา ไม่จำเป็นต้องมีไลบรารีภายนอกหรือโครงสร้างข้อมูลที่ซับซ้อน อย่างไรก็ตาม วิธีการนี้อาจไม่มีประสิทธิภาพสำหรับชุดข้อมูลขนาดใหญ่ การลบองค์ประกอบออกจากจุดเริ่มต้นของรายการ (pop(0)) ใช้เวลาเชิงเส้น ซึ่งอาจทำให้เกิดปัญหาด้านประสิทธิภาพได้

หมายเหตุ สำหรับแอปพลิเคชันที่ต้องการประสิทธิภาพสูงหรือแอปพลิเคชันที่ต้องจัดการกับข้อมูลจำนวนมาก ให้เปลี่ยนไปใช้ collections.deque เพื่อความซับซ้อนของเวลาคงที่สำหรับทั้งการเข้าคิวและการเข้าคิว

เริ่มต้นด้วยการสร้างรายการเพื่อแสดงคิวของเรา:

queue = []

กระบวนการเพิ่มองค์ประกอบที่ส่วนท้ายของคิว (การจัดคิว) ไม่มีอะไรอื่นนอกจากการผนวกองค์ประกอบเหล่านั้นเข้ากับรายการ:


queue.append('A')
queue.append('B')
queue.append('C')
print(queue) 

นอกจากนี้ การลบองค์ประกอบออกจากด้านหน้าของคิว (การแยกคิว) ก็เทียบเท่ากับการลบองค์ประกอบแรกของรายการ:


queue.pop(0)
print(queue) 

การใช้ คอลเลกชัน.deque เพื่อดำเนินการคิว

แนวทางนี้มีประสิทธิภาพสูงเช่น deque ถูกนำมาใช้โดยใช้ รายการที่เชื่อมโยงแบบทวีคูณ. รองรับการต่อท้าย O(1) อย่างรวดเร็วและป๊อปจากปลายทั้งสองข้าง ข้อเสียของวิธีนี้ก็คือ เล็กน้อย ใช้งานง่ายน้อยกว่าสำหรับผู้เริ่มต้น

ก่อนอื่นเราจะนำเข้าไฟล์ deque วัตถุจาก collections โมดูลและเริ่มต้นคิวของเรา:

from collections import deque queue = deque()

ตอนนี้เราสามารถใช้ append() วิธีการจัดคิวองค์ประกอบและ popleft() วิธีการแยกองค์ประกอบออกจากคิว:

ดูคู่มือเชิงปฏิบัติสำหรับการเรียนรู้ Git ที่มีแนวทางปฏิบัติที่ดีที่สุด มาตรฐานที่ยอมรับในอุตสาหกรรม และเอกสารสรุปรวม หยุดคำสั่ง Googling Git และจริงๆ แล้ว เรียน มัน!


queue.append('A')
queue.append('B')
queue.append('C')
print(queue) queue.popleft()
print(queue) 

การใช้หลาม คิว โมดูลสำหรับการดำเนินการคิว

พื้นที่ queue โมดูลในไลบรารีมาตรฐานของ Python มอบแนวทางที่พิเศษยิ่งขึ้นในการจัดการคิว ซึ่งรองรับกรณีการใช้งานที่หลากหลาย:

  • SimpleQueue – คิว FIFO พื้นฐาน
  • LifoQueue – คิว LIFO โดยพื้นฐานแล้วคือสแต็ก
  • ลำดับความสำคัญ – องค์ประกอบจะถูกจัดคิวตามลำดับความสำคัญที่ได้รับมอบหมาย

หมายเหตุ เลือกใช้ queue โมดูลที่ถูกออกแบบให้เป็น ปลอดภัยต่อด้าย. เพื่อให้แน่ใจว่าการดำเนินการพร้อมกันในคิวจะไม่นำไปสู่ผลลัพธ์ที่คาดเดาไม่ได้

แนวทางนี้ดีมากเนื่องจากได้รับการออกแบบมาอย่างชัดเจนสำหรับการดำเนินการคิว แต่พูดตามตรง มันอาจจะเกินความจำเป็นสำหรับสถานการณ์ง่ายๆ

เอาล่ะ มาเริ่มใช้กันเลย queue โมดูลโดยนำเข้าสู่โครงการของเรา:

import queue

เนื่องจากเรากำลังใช้คิว FIFO แบบง่าย เราจะเริ่มต้นโดยใช้ SimpleQueue() ตัวสร้าง:

q = queue.SimpleQueue()

การดำเนินการจัดคิวและการจัดคิวจะดำเนินการโดยใช้ put() และ get() วิธีการจาก queue โมดูล:


q.put('A')
q.put('B')
q.put('C')
print(q.queue) q.get()
print(q.queue) 

หมายเหตุ การดำเนินการคิวอาจทำให้เกิดข้อยกเว้นซึ่งหากไม่ได้รับการจัดการ อาจขัดขวางการทำงานของแอปพลิเคชันของคุณได้ เพื่อป้องกันสิ่งนั้น ให้รวมการดำเนินการคิวของคุณไว้ try-except บล็อก

ตัวอย่างเช่น จัดการกับ queue.Empty ข้อยกเว้นเมื่อทำงานกับ queue โมดูล:

import queue q = queue.SimpleQueue() try: item = q.get_nowait()
except queue.Empty: print("Queue is empty!")

การดำเนินการใดให้เลือก

การเลือกใช้งานคิวของคุณใน Python ควรสอดคล้องกับข้อกำหนดของแอปพลิเคชันของคุณ หากคุณกำลังจัดการข้อมูลปริมาณมากหรือต้องการประสิทธิภาพที่เหมาะสมที่สุด collections.deque เป็นทางเลือกที่น่าสนใจ อย่างไรก็ตาม สำหรับแอปพลิเคชันแบบมัลติเธรดหรือเมื่อมีลำดับความสำคัญเข้ามามีบทบาท queue โมดูลนำเสนอโซลูชั่นที่แข็งแกร่ง สำหรับสคริปต์ด่วนหรือเมื่อคุณเพิ่งเริ่มต้น รายการ Python อาจเพียงพอ แต่ควรระวังข้อผิดพลาดด้านประสิทธิภาพที่อาจเกิดขึ้นอยู่เสมอ

หมายเหตุ พลิกโฉมวงล้อด้วยการดำเนินการคิวแบบกำหนดเองเมื่อ Python มอบโซลูชันในตัวที่ทรงพลังอยู่แล้ว
ก่อนที่จะสร้างโซลูชันแบบกำหนดเอง ให้ทำความคุ้นเคยกับข้อเสนอในตัวของ Python เช่น deque และ queue โมดูล. โดยส่วนใหญ่แล้ว พวกเขาตอบสนองความต้องการที่หลากหลาย ช่วยประหยัดเวลาและลดข้อผิดพลาดที่อาจเกิดขึ้น

เจาะลึก: แนวคิดคิวขั้นสูงใน Python

สำหรับผู้ที่เข้าใจกลไกพื้นฐานของคิวและกระตือรือร้นที่จะเจาะลึกยิ่งขึ้น Python นำเสนอแนวคิดและเทคนิคขั้นสูงมากมายเพื่อปรับแต่งและเพิ่มประสิทธิภาพการดำเนินการตามคิว มาเปิดเผยแง่มุมที่ซับซ้อนเหล่านี้กัน ซึ่งจะทำให้คุณมีคลังเครื่องมือเพื่อรับมือกับสถานการณ์ที่ซับซ้อนมากขึ้น

คิวปลายคู่ด้วย เดค

ในขณะที่เราเคยสำรวจมาแล้ว deque ในฐานะคิว FIFO ยังรองรับการดำเนินการ LIFO (เข้าก่อน-ออกก่อน) อีกด้วย ช่วยให้คุณสามารถผนวกหรือป๊อปองค์ประกอบจากปลายทั้งสองด้านด้วยความซับซ้อน O(1):

from collections import deque dq = deque()
dq.appendleft('A') dq.append('B') dq.pop() dq.popleft() 

PriorityQueu ในการดำเนินการ

การใช้คิว FIFO แบบง่ายเมื่อลำดับการประมวลผลขึ้นอยู่กับลำดับความสำคัญอาจนำไปสู่ความไร้ประสิทธิภาพหรือผลลัพธ์ที่ไม่พึงประสงค์ ดังนั้น หากใบสมัครของคุณต้องการให้องค์ประกอบบางอย่างได้รับการประมวลผลก่อนองค์ประกอบอื่นตามเกณฑ์บางอย่าง จ้าง PriorityQueue. เพื่อให้แน่ใจว่าองค์ประกอบจะได้รับการประมวลผลตามลำดับความสำคัญที่ตั้งไว้

ดูวิธีที่เรากำหนดลำดับความสำคัญสำหรับองค์ประกอบที่เราเพิ่มลงในคิว สิ่งนี้ต้องการให้เราผ่านสิ่งอันดับเป็นอาร์กิวเมนต์ของ put() วิธี. สิ่งทูเปิลควรมีลำดับความสำคัญเป็นองค์ประกอบแรกและค่าจริงเป็นองค์ประกอบที่สอง:

import queue pq = queue.PriorityQueue()
pq.put((2, "Task B"))
pq.put((1, "Task A")) pq.put((3, "Task C")) while not pq.empty(): _, task = pq.get() print(f"Processing: {task}")

สิ่งนี้จะทำให้เรามีสิ่งต่อไปนี้:

Processing: Task A
Processing: Task B
Processing: Task C

สังเกตว่าเราเพิ่มองค์ประกอบในลำดับที่แตกต่างจากที่จัดเก็บไว้ในคิวอย่างไร นั่นเป็นเพราะลำดับความสำคัญที่เราได้กำหนดไว้ใน put() วิธีการเพิ่มองค์ประกอบลงในคิวลำดับความสำคัญ

การใช้คิวแบบวงกลม

คิวแบบวงกลม (หรือบัฟเฟอร์แบบวงแหวน) คือโครงสร้างข้อมูลขั้นสูงที่องค์ประกอบสุดท้ายเชื่อมต่อกับองค์ประกอบแรก เพื่อให้แน่ใจว่ามีการไหลแบบวงกลม deque สามารถเลียนแบบพฤติกรรมนี้โดยใช้มัน maxlen คุณสมบัติ:

from collections import deque circular_queue = deque(maxlen=3)
circular_queue.append(1)
circular_queue.append(2)
circular_queue.append(3) circular_queue.append(4)
print(circular_queue) 

สรุป

Queues เป็นพื้นฐานแต่ทรงพลัง ค้นหาแก่นแท้ของแอปพลิเคชันต่างๆ ในโลกแห่งความเป็นจริงและปัญหาทางการคำนวณ ตั้งแต่การกำหนดเวลางานในระบบปฏิบัติการไปจนถึงการจัดการกระแสข้อมูลในตัวจัดคิวงานพิมพ์หรือคำขอของเว็บเซิร์ฟเวอร์ ผลกระทบของคิวนั้นมีผลกระทบอย่างกว้างขวาง

Python นำเสนอชุดเครื่องมือและไลบรารีที่หลากหลายเพื่อทำงานกับคิว จากคิวตามรายการอย่างง่ายสำหรับสคริปต์ด่วนไปจนถึงประสิทธิภาพสูง deque สำหรับแอปพลิเคชันที่เน้นประสิทธิภาพ ภาษาจะตอบสนองความต้องการที่หลากหลายอย่างแท้จริง

ประทับเวลา:

เพิ่มเติมจาก สแต็ค