Python 遍歷字典的若幹方法

来源:https://www.cnblogs.com/edisonfish/archive/2023/09/04/17677872.html
-Advertisement-
Play Games

哈嘍大家好,我是鹹魚 我們知道字典是 Python 中最重要且最有用的內置數據結構之一,它們無處不在,是語言本身的基本組成部分 我們可以使用字典來解決許多編程問題,那麼今天我們就來看看**如何在 Python 中遍歷字典** 全文內容:https://realpython.com/iterate-t ...


哈嘍大家好,我是鹹魚

我們知道字典是 Python 中最重要且最有用的內置數據結構之一,它們無處不在,是語言本身的基本組成部分

我們可以使用字典來解決許多編程問題,那麼今天我們就來看看如何在 Python 中遍歷字典

全文內容:https://realpython.com/iterate-through-dictionary-python/

ps:文中提到的 Python 指的是 CPython 實現;

譯文如下:

字典是 Python 的基石。這門語言的很多方面都是圍繞著字典構建的

模塊、類、對象、globals()locals() 都是字典與 Python 實現緊密聯繫的例子

以下是 Python 官方文檔定義字典的方式:

An associative array, where arbitrary keys are mapped to values. The keys can be any object with __hash__() and __eq__() methods

需要註意的是:

  • 字典將鍵映射到值,並將它們存儲在數組或集合中。鍵值對通常稱為 items
  • 字典鍵必須是可哈希類型,這意味著它們必須具有在鍵的生命周期內永遠不會更改的哈希值

與序列不同,序列是支持使用整數索引進行元素訪問的可迭代對象,字典按鍵編製索引。這意味著我們可以使用關聯的鍵而不是整數索引來訪問存儲在字典中的值

字典中的鍵很像 set ,它是可哈希和唯一對象的集合。由於鍵需要可哈希處理,因此不能將可變對象用作字典鍵(即鍵不能是可變數據類型)

另一方面,字典值可以是任何 Python 類型,無論它們是否可哈希。從字面上看,對值沒有任何限制。我們可以使用任何數據類型作為 Python 字典中的值

在Python 3.6之前,字典是無序的數據結構。這意味著 item 的順序通常與插入順序不匹配

>>> # Python 3.5
>>> likes = {"color": "blue", "fruit": "apple", "pet": "dog"}

>>> likes
{'color': 'blue', 'pet': 'dog', 'fruit': 'apple'}

可以看到,生成的詞典中 item 的順序與最初插入 item 的順序不匹配

在 Python 3.6 及更高版本中,字典的鍵和值保持與將它們插入底層字典的順序相同。即從3.6 開始,字典變成了緊湊有序的數據結構

>>> # Python 3.6
>>> likes = {"color": "blue", "fruit": "apple", "pet": "dog"}

>>> likes
{'color': 'blue', 'fruit': 'apple', 'pet': 'dog'}

保持 item 有序是一個非常有用的功能。但是,如果使用的代碼支持較舊的 Python 版本,則不能依賴此功能,因為它可能生成 bug,對於較新的版本,依賴該特性是完全安全的

字典的另一個重要特征是它們是可變的數據類型。這意味著我們可以根據需要就地添加、刪除和更新其項目

值得註意的是,這種可變性也意味著不能將字典用作另一個字典中的鍵

如何在 python 中遍歷字典

Python 開發人員經常會遇到這樣的情況:在對其鍵值對執行某些操作時,需要遍歷現有字典

因此,瞭解 Python 中字典迭代的不同方法非常重要。保持 item 有序是一個非常有用的功能

  • 直接遍歷字典

Python 的字典有一些特殊的方法,Python 在內部使用它們來執行一些操作

這兩個方法的命名約定是,在方法名的開頭和末尾分別添加兩個下劃線

可以使用內置 dir() 函數獲取任何 Python 對象提供的方法和屬性的列表。如果使用空字典作為參數運行 dir() ,則將獲得 dict 該類的所有方法和屬性

>>> dir({})
['__class__', '__contains__', '__delattr__', ... , '__iter__', ...]

可以看到'__iter__' 這個屬性,這是 Python 在需要容器數據類型的迭代器時自動調用的方法

該方法應該返回一個新的迭代器對象,該對象允許我們遍歷底層容器類型中的所有項

對於 Python 字典,預設情況下允許 .__iter__() 直接迭代鍵。如果你直接在 for 迴圈中使用字典,Python 將自動調用 .__iter__() 屬性,你會得到一個遍歷其鍵的迭代器

>>> likes = {"color": "blue", "fruit": "apple", "pet": "dog"}

>>> for key in likes:
...     print(key)
...
color
fruit
pet

Python 足夠聰明,知道 likes 是一個字典,並且它實現了.__iter__()。在這個例子中,Python自動調用.__iter__(),這允許迭代 likes 字典的鍵

這是在 Python 中遍歷字典的主要方法——你只需要把字典直接放進一個 for 迴圈中

如果將此方法與 [key] 運算符一起使用,則可以在迴圈訪問鍵時訪問字典的值

>>> for key in likes:
...     print(key, "->", likes[key])
...
color -> blue
fruit -> apple
pet -> dog

在本例中,同時使用 key likes[key] 來分別訪問目標字典的鍵和值

儘管在 Python 中直接遍歷字典非常簡單,但字典提供了更方便、更明確的工具來獲得相同的結果

.items() 該方法就是這種情況,它定義了一種快速迭代字典的 item 或鍵值對的方法

  • .items()方法遍歷字典 item

使用字典時,同時迴圈訪問鍵和值可能是一個常見要求。 .items() 方法返回一個視圖對象,其中包含字典的項作為鍵值元組:

>>> likes = {"color": "blue", "fruit": "apple", "pet": "dog"}

>>> likes.items()
dict_items([('color', 'blue'), ('fruit', 'apple'), ('pet', 'dog')])

字典視圖對象提供字典項的動態視圖。在這裡,動態意味著當字典更改時,視圖會反映這些更改

視圖是可迭代的,因此我們可以使用調用 .items() 生成的視圖對象迴圈訪問字典中的項,如以下示例所示:

>>> for item in likes.items():
...     print(item)
...
('color', 'blue')
('fruit', 'apple')
('pet', 'dog')

在此示例中, 返回一個視圖對象,該對象一次生成一個鍵值對, .items() 並允許我們迴圈訪問它們

如果仔細觀察產生的各個項目 .items() ,那麼會註意到它們是 tuple 對象:

>>> for item in likes.items():
...     print(item)
...     print(type(item))
...
('color', 'blue')
<class 'tuple'>
('fruit', 'apple')
<class 'tuple'>
('pet', 'dog')

可以看到所有的 item 都是元組。一旦知道了這一點,就可以使用元組解包來並行地遍歷鍵和值

要通過鍵和值實現並行迭代,只需將每個 item 的元素解壓縮為兩個不同的變數:一個用於鍵,另一個用於值

>>> for key, value in likes.items():
...     print(key, "->", value)
...
color -> blue
fruit -> apple
pet -> dog

for 迴圈頭中的 key 和 value 變數執行解包操作。每次迴圈運行時,key獲得對當前鍵的引用,value獲得對值的引用

這樣,我們就可以更好地控制字典內容。因此,我們將能夠以可讀和 python 的方式分別處理鍵和值

  • .keys() 方法遍歷字典的鍵

Python 字典提供了第二種遍歷其鍵的方法。除了在迴圈中直接使用目標字典外,還可以使用.keys()方法

這個方法返回一個只包含字典鍵的視圖對象

>>> likes = {"color": "blue", "fruit": "apple", "pet": "dog"}

>>> likes.keys()
dict_keys(['color', 'fruit', 'pet'])

該方法 .keys() 返回一個對象,該對象提供 likes 鍵的動態視圖。可以使用此視圖對象迴圈訪問字典鍵

>>> for key in likes.keys():
...     print(key)
...
color
fruit
pet

當您在 likes上調用 .keys() 時,將獲得鍵的視圖。Python 知道視圖對象是可迭代的,所以它開始迴圈

為什麼要使用 .keys() 而不是直接遍歷字典。簡單來說,顯式地使用 .keys()可以讓你更好地表達只遍歷鍵的意圖

  • .values() 方法遍歷字典值

在遍歷字典時面臨的另一個常見需求是只遍歷值。方法是使用 .values() 方法,它會返回一個包含底層字典中的值的視圖

>>> likes = {"color": "blue", "fruit": "apple", "pet": "dog"}

>>> likes.values()
dict_values(['blue', 'apple', 'dog'])

上面的代碼返回一個視圖對象, .values() 返回一個視圖對象。

與其他視圖對象一樣,的結果 .values() 也是可迭代的,因此可以在迴圈中使用它

>>> for value in likes.values():
...     print(value)
...
blue
apple
dog

使用 .values() ,只能訪問目標字典的值

  • 在迭代期間更改值

有時,在 Python 中迭代字典時需要更改字典中的值

在下麵的例子中,你在一個字典中更新了一堆產品的價格:

>>> fruits = {"apple": 0.40, "orange": 0.35, "banana": 0.25}

>>> for fruit, price in fruits.items():
...     fruits[fruit] = round(price * 0.9, 2)
...

>>> fruits
{'apple': 0.36, 'orange': 0.32, 'banana': 0.23}

在上面的例子中需要註意的是:為了更新值,我們使用了原始的字典,而不是像price = round(price * 0.9, 2)這樣直接更新當前的價格

如果像price = round(price * 0.9, 2)這樣,重新分配水果或價格並沒有反映在原來的字典中

就會導致丟失對字典的引用,這樣並沒有實現更改字典中的任何內容

  • 在迭代期間安全地刪除 item

由於 Python 字典是可變的,我們可以根據需要從中刪除現有的 item

在下麵的示例中,我們根據項的特定值選擇性地刪除項

註意,為了在遍歷字典時安全地縮小字典,我們需要使用一個副本

>>> fruits = {"apple": 0.40, "orange": 0.35, "banana": 0.25}

>>> for fruit in fruits.copy():
...     if fruits[fruit] >= 0.30:
...         del fruits[fruit]
...

>>> fruits
{'banana': 0.25}

在本例中,使用 .copy() 創建目標字典fruits的淺副本。然後迴圈遍歷副本,同時從原始字典中刪除項,在本例中,使用 del 語句刪除字典項

但是也可以使用 .pop() 將目標鍵作為參數

如果在嘗試刪除迴圈中的 item 時不使用目標詞典的副本,則會收到錯誤

>>> fruits = {"apple": 0.40, "orange": 0.35, "banana": 0.25}

>>> for fruit in fruits:
...     if fruits[fruit] >= 0.30:
...         del fruits[fruit]
...
Traceback (most recent call last):
  File "<input>", line 1, in <module>
    for fruit in fruits:
RuntimeError: dictionary changed size during iteration

當你試圖在迭代過程中從字典中刪除一個 item 時,Python 會引發 RuntimeError

由於原始字典的大小發生了變化,因此如何繼續迭代是不明確的。因此,要避免這個問題,請始終在迭代中使用字典的副本

遍歷期間對字典的操作

  • 根據值來過濾 item

有時候我們希望在原字典的前提下創建一個只包含滿足特定條件的新字典

我們可以在遍歷原字典的時候加上條件判斷

>>> numbers = {"one": 1, "two": 2, "three": 3, "four": 4}

>>> small_numbers = {}

>>> for key, value in numbers.items():
...     if value <= 2:
...         small_numbers[key] = value
...

>>> small_numbers
{'one': 1, 'two': 2}

在此示例中,篩選值小於的項目 2 ,並將它們添加到 small_numbers 字典中

還有另一種技術可以用來從字典中過濾 item。因為鍵的視圖對象類似於 Python 集合對象

因此,它們支持集合操作,例如並集、交集和差分。可以利用這種類似集合的行為從字典中過濾某些鍵

>>> fruits = {"apple": 0.40, "orange": 0.35, "banana": 0.25}

>>> fruits.keys() - {"orange"}
{'apple', 'banana'}

還可以更簡潔

>>> numbers = {"one": 1, "two": 2, "three": 3, "four": 4}

>>> {key: value for key, value in numbers.items() if value <= 2}
{'one': 1, 'two': 2}

或者通過計算字典的鍵與一組不需要的鍵之間的差分而獲得的鍵集構建一個新詞典

>>> non_citrus = {}

>>> for key in fruits.keys() - {"orange"}:
...     non_citrus[key] = fruits[key]
...

>>> non_citrus
{'apple': 0.4, 'banana': 0.25}
  • 算術運算

在遍歷字典時,我們可以對字典的值進行計算

>>> incomes = {"apple": 5600.00, "orange": 3500.00, "banana": 5000.00}
>>> total_income = 0.00

>>> for income in incomes.values():
...     total_income += income
...

>>> total_income
14100.0

或者使用內置的 sum() 函數。把字典中的值作為參數直接傳遞給 sum() 來求和

>>> incomes = {"apple": 5600.00, "orange": 3500.00, "banana": 5000.00}
>>> sum(incomes.values())
14100.0
  • 鍵值交換

我們可以在遍歷的時候交換字典的鍵和值

>>> numbers = {"one": 1, "two": 2, "three": 3, "four": 4}
>>> swapped = {}

>>> for key, value in numbers.items():
...     swapped[value] = key
...

>>> swapped
{1: 'one', 2: 'two', 3: 'three', 4: 'four'}

更簡潔的寫法

>>> numbers = {"one": 1, "two": 2, "three": 3, "four": 4}

>>> {value: key for key, value in numbers.items()}
{1: 'one', 2: 'two', 3: 'three', 4: 'four'}

需要註意的是,原始字典值中的數據必須是可哈希數據類型

我們還可以將內置 zip() 函數與 dict() 構造函數一起使用

>>> dict(zip(numbers.values(), numbers.keys()))
{1: 'one', 2: 'two', 3: 'three', 4: 'four'}

上面的示例中,通過 zip() 生成值鍵對的元組,然後,使用生成的元組作為參數並 dict() 構建所需的字典

字典推導式

與列表推導式不同,字典推導式需要一個映射到值的鍵

>>> categories = ["color", "fruit", "pet"]
>>> objects = ["blue", "apple", "dog"]

>>> likes = {key: value for key, value in zip(categories, objects)}
>>> likes
{'color': 'blue', 'fruit': 'apple', 'pet': 'dog'}

上面的對象中, zip() 接收兩個可迭代對象( categoriesobjects )生成了一個 tuple 對象,然後被解壓縮到 keyvalue 中,最終用於創建新的所需字典

更簡潔的方法如下:

>>> categories = ["color", "fruit", "pet"]
>>> objects = ["blue", "apple", "dog"]

>>> dict(zip(categories, objects))
{'color': 'blue', 'fruit': 'apple', 'pet': 'dog'}

zip() 函數從原始列表生成鍵值對,而 dict() 構造函數負責創建新字典


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • > 講解Go語言從編譯到執行全周期流程,每一部分都會包含豐富的技術細節和實際的代碼示例,幫助大家理解。 > 關註微信公眾號【TechLeadCloud】,分享互聯網架構、雲服務技術的全維度知識。作者擁有10+年互聯網服務架構、AI產品研發經驗、團隊管理經驗,同濟本復旦碩,復旦機器人智能實驗室成員,阿 ...
  • 最近在公司的項目中,編寫了幾個自定義的 Exception 類。提交 PR 的時候,sonarqube 提示這幾個自定義異常不符合 ISerializable patten. 花了點時間稍微研究了一下,把這個問題解了。今天在此記錄一下,可能大家都會幫助到大家。 ## 自定義異常 編寫一個自定義的異常 ...
  • 我們在使用一些需要購買版權的軟體產品時,或者我們做的商業軟體需要進行售賣,為了收取費用,一般需要一個軟體使用許可證,然後輸入這個許可到軟體里就能夠使用軟體。簡單的是一串序列碼或者一個許可證文件,複雜的是一個定製化插件包。於是有的小伙伴就開始好奇這個許可是怎麼實現的,特別是在離線情況下它是怎麼給軟體授... ...
  • # EF Core併發控制 # 併發控制概念 1. 併發控制:避免多個用戶同時操作資源造成的併發衝突問題。 2. 最好的解決方案:非資料庫解決方案 3. 資料庫層面的兩種策略:悲觀、樂觀 # 悲觀鎖 悲觀併發控制一般採用行鎖 ,表鎖等排他鎖對資源進行鎖定,確保同時只有一個使用者操作被鎖定的資源。 E ...
  • # Unity UGUI的Scrollbar(滾動條)組件的介紹及使用 ## 一、什麼是Scrollbar組件? Scrollbar組件是Unity中UGUI系統提供的一種UI組件,主要用於在UI界面中提供滾動條功能,使用戶可以通過滾動條來查看超出屏幕範圍的內容。 ## 二、Scrollbar組件是 ...
  • 在我寫[在.NET Framework中使用RocketMQ(阿裡雲版)]這篇博客的時候,因為封裝了很多代碼在單獨的DLL中,包括生產者、消費者以及官方SDK等等,然後都在博客中體現出來導致博客大量代碼,然後有位讀者就建議打包成NuGet包,大家也可以直接安裝調用,我也覺得很不錯,於是就有了這篇文章... ...
  • # Redis 文章內容主要參考b站 運維實戰課程 的redis視頻:[redis的課程介紹_嗶哩嗶哩_bilibili](https://www.bilibili.com/video/BV1cP4y1D7yh?p=1) ## 簡介 1.Redis是一個緩存資料庫,主要是做緩存。什麼是緩存?也就是緩 ...
  • [toc] # Linux運維工程師面試題(6) > 祝各位小伙伴們早日找到自己心儀的工作。 > 持續學習才不會被淘汰。 > 地球不爆炸,我們不放假。 > 機會總是留給有有準備的人的。 > 加油,打工人! ## 1 資料庫事務的四個特性及含義 資料庫事務的4個特性:原⼦性、持久性、⼀致性、隔離性 - ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...