Menu
快讀
  • 旅遊
  • 生活
    • 美食
    • 寵物
    • 養生
    • 親子
  • 娛樂
    • 動漫
  • 時尚
  • 社會
  • 探索
  • 故事
  • 科技
  • 軍事
  • 国际
快讀

什麽是隊列?(Python隊列)

2020 年 1 月 3 日 咪哥杂谈

前言

上篇文章介紹了 Python 中的多線程。今天來介紹下編程中常會用到的一個數據結構 – 隊列。

不知道大家是否還記得什麽是數據結構呢?在很早很早以前,Python小課堂的初期,講了許多 Python 原生的數據結構。比如 list、tuple、dict 等。。。

既然叫數據結構,實際上就是爲了給計算機存儲數據用的一種結構體。不同的數據結構都有其不同的特點。那今天就來簡單地聊聊隊列!

隊列的概念

抛開計算機知識體系,在咱們的生活中,隊列這個詞其實挺好想象的,因爲無時無刻都可以見到。比如等公交的時候,需要排隊。比如買東西交錢的時候,也要排隊。在這些例子中,由人們有序形成的隊形就叫隊列。

生活中的排隊,有沒有什麽特性而言呢?大家可以思考下,再往下看。

普通隊列的特性,即先進先出(FIFO,first in first out)。對應到生活中,怎麽理解這個先進先出?其實很好理解。

拿排隊買東西來說,每次排在隊首的人,交完錢肯定是當前隊列中第一個離開收銀台的人。當隊首的人離開了,那麽後面的所有人都要往前走,繼續結賬。

對應到計算機中的隊列,就是因爲第一個人先排的隊,所以他第一個交完錢就可以離開了,即先進先出。(多說句,計算機世界許多東西其實就是抽象的現實世界示例。)

心細的同學會發現,在上面將普通兩字標粗了,那一定還有一些其它的常用特殊隊列,比如優先級隊列。(PriorityQueue)

這次拿去銀行辦業務來舉例。生活中我們去銀行辦理業務,一般都需要去機器拿號,然後等待著櫃台業務人員叫號。叫到你,你就過去處理就行了。但是銀行是有 vip 服務的,擁有 vip 權益的人可以更快的享受到業務辦理,也就是說人家比你有更高的優先權。vip特權通道,你值得擁有!

了解了生活中的例子,再來看看比較專業的定義:

優先級隊列(priority queue) 是0個或多個元素的集合,每個元素都有一個優先權,對優先級隊列執行的操作有(1)查找(2)插入一個新元素 (3)刪除 一般情況下,查找操作用來搜索優先權最大的元素,刪除操作用來刪除該元素 。對于優先權相同的元素,可按先進先出次序處理或按任意優先權進行。

百度百科

也就是說,在優先級隊列中,每個人都有一個優先權對應,誰的優先權高,誰就會先被處理。大家了解即可。

示例演示

示例情景:

假設下面有 6 個美少女,她們准備去量身高,恰好這幾個妹紙是按照從高到低,從大到小排好隊的。

什麽是隊列?(Python隊列)

每走一個去量身高,這個隊列中就會少一個人。當然,隊首在左,隊尾在右,于是她們的變化是下面這樣:

什麽是隊列?(Python隊列)

什麽是隊列?(Python隊列)

。。。。。。省略,直到:

什麽是隊列?(Python隊列)

代碼演示

是不是好多人看到這裏就不打算看了。。不是讓你來看美少女的餵。。。下面才是重點~

第一部分代碼:

import queue
import threading

num_worker_threads = 5

def do_work(beauty_dict):
    print(f"妹紙名字{beauty_dict['name']},年齡{beauty_dict['age']}")

def worker():
    while True:
        item = q.get()
        if item is None:
            break
        do_work(item)
        q.task_done()

簡單的講解下,在 Python3 中,有個模塊叫 queue。裏面實現了幾個隊列的數據結構。首先看 do_work() 函數,其中它就是用來打印妹子姓名和年齡的。worker() 函數中寫了一層死循環,只要隊列中有妹紙的數據,就一直執行打印,直到隊列中的妹紙都沒了,就跳出。

第二部分代碼:

q = queue.Queue()
threads = []
for i in range(num_worker_threads):
    t = threading.Thread(target=worker)
    t.start()
    threads.append(t)

beauty_girls = [{"name": "小H", "age": 23},
                {"name": "小E", "age": 22},
                {"name": "小D", "age": 21},
                {"name": "小C", "age": 20},
                {"name": "小B", "age": 19},
                {"name": "小A", "age": 18},
                ]

for item in beauty_girls:
    q.put(item)

# block until all tasks are done
q.join()

# stop workers
for i in range(num_worker_threads):
    q.put(None)
for t in threads:
    t.join()

首先創建隊列,其次,讓這 6 個美少女開始依次排入到隊列中,開啓多線程去執行 worker() 這個函數。worker() 函數就是第一部分代碼中,從隊列裏一個個取出妹紙,在調用 do_work() 打印她們的姓名和年齡。

關于隊列的 join() 方法,可以看到官方給的英文注釋,大意是當所有任務完成時才繼續執行後面的代碼,否則處于阻塞狀態。

代碼中涉及的方法,老規矩,希望大家可以自己去查閱 Python 官方文檔,搜索 queue 即可看到。當然如果懶得動手的話,筆者這裏截圖幾個常用方法:

將妹紙放入隊列中:

什麽是隊列?(Python隊列)

從隊列中獲取妹紙:

什麽是隊列?(Python隊列)

獲取隊列中妹紙的個數:

什麽是隊列?(Python隊列)

總結

通過兩篇文章,簡單的介紹了一下多線程和隊列,目的是爲了接下來的多線程隊列爬蟲示例做准備,如果對這些不了解的話,在後面的代碼中是很難看懂的。

關于隊列的使用,最常用的方法應該就是放入、獲取、判斷隊列的大小。其實這三點在大部分數據結構裏都是常用的操作,熟練掌握即可。

本章完整代碼,就是文中第一部分和第二部分的代碼拼接,因爲太長,所以分開講了下。

如果大家有什麽問題想溝通,可以留言交流哈!

相關文章:

  • 如何加密你的 Python 代碼
  • 有哪些足不出戶,能用十天掌握的新技能?
  • 戳破針對「木蘭」編程語言的拙劣謠言
  • 華爲都開始用Linux了,你還不來了解下全球第三大桌面操作系統?
  • 12小時刪!付費買的資源,請低調使用!
  • 懂Excel輕松入門Python數據分析包pandas(二十七):IF函數代替者
科技

發佈留言 取消回覆

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

©2025 快讀 | 服務協議 | DMCA | 聯繫我們