當前位置:
首頁 > 知識 > ChainMap:將多個字典視為一個,解鎖Python超能力。

ChainMap:將多個字典視為一個,解鎖Python超能力。


簡而言之ChainMap:將多個字典視為一個,解鎖Python超能力。


Python標準庫中的集合模塊包含許多為性能而設計的實用的數據結構。著名的包括命名元組或計數器。


今天,通過實例,我們來看看鮮為人知的

ChainMap

。通過瀏覽具體的示例,我希望給你一個提示,關於在更高級的Python工作中使用ChainMap將如何從中受益。

免責聲明:這篇文章是關於Python的一個相當高級的特性。如果你剛入門,請等一等!


ChainMap是什麼?


ChainMap是由Python標準庫提供的一種數據結構,允許你將多個字典視為一個。


ChainMap上的官方文檔如下:


ChainMap將多個dict或其他映射組合在一起以創建單個可更新視圖。[…] 查找基礎映射,直到找到key為止。[…]如果其中一個基礎映射得到更新,這些更改將反映在ChainMap中。 […] 支持所有常用的字典方法。


換句話說:

ChainMap是一個基於多dict的可更新的視圖,它的行為就像一個普通的dict。


你以前可能從來沒有聽說過ChainMap,你可能會認為ChainMap的使用情況是非常特定的。坦率地說,你是對的。


我知道的用例包括:




  • 通過多個字典搜索



  • 提供鏈預設值



  • 經常計算字典子集的性能關鍵的應用程序


我們將通過兩個例子來說明。


注意:這兩個例子是受到Mike Driscoll在The Mouse vs. The Python寫的一篇文章的啟發。為了我的目的,我已經調整了它們,但一定要閱讀他的帖子另一個關於ChainMap的觀點!



示例:購物清單


作為使用ChainMap的第一個例子,讓我們考慮一張購物清單。我們的清單可能包含玩具,電腦,甚至衣服。所有這些條目都有價格,所以我們將把我們的條目存儲在名稱價格映射中。



現在我們可以使用ChainMap在這些不同的集合上建立一個單一的視圖:


這使得我們可以查詢清單,

就像它是一個單一的字典



正如官方文檔所述,ChainMap支持所有常用的字典方法。我們可以使用.get()來搜索可能不存在的條目,或者使用 .pop()刪除條目。



如果我們現在把玩具添加到toys字典里,它也將在清單中可用。這是ChainMap的可更新的方面。



Oh和ChainMap有一個恰當的字元串表示形式:



一個很好的特點是,在我們的例子中,toys, computers和clothing都是在相同的上下文中(解釋器),它們可以來自完全不同的模塊或包。這是因為ChainMap

通過引用

存儲底層字典。


第一個例子是使用ChainMap一次搜索多個字典。


事實上,當構建ChainMap時,我們所做的就是有效地構建一系列字典。當查找清單中的一個項時,toys首先被查找,然後是computers,最後是clothing。



                              ChainMap真的只是一個映射鏈!


實際上,ChainMap的另一個任務是

維護鏈的默認值


我們將以一個命令行應用程序的例子來說明這是什麼意思。


示例:CLI配置


讓我們面對現實,管理命令行應用程序的配置可能是困難的。

配置來自多個源:命令行參數、環境變數、本地文件等。


我們通常實施

優先順序

的概念:如果A和B都定義參數P,A的P值將被使用,因為它的優先順序高於B。


例如,如果傳遞了命令行參數,我們可能希望在環境變數上使用命令行參數。


如何輕鬆地管理配置源的優先順序?


一個答案是將所有配置源存儲在ChainMap中。


因為ChainMap中的查找是連續地對每個底層映射執行的

(按照他們傳給構造函數的順序),所以我們可以很容易地實現我們尋找的優先順序。


下面是一個簡單的命令行應用程序。調試參數從命令行參數、環境變數或硬編碼默認值中提取:


在執行腳本時,我們可以檢查是否首先在命令行參數中查找debug,然後是環境變數,最後是默認值:



整潔,對吧?


我為什麼關心?


坦率地說,ChainMap是那些你可以忽略的Python特性之一。


還有其他ChainMap的替代方案。例如,使用更新循環——例如創建一個dict並用字典.update()它——可能奏效。但是,這隻有在您不需要跟蹤項目的起源時才有效,就像我們的多源CLI配置示例中的情況一樣。


但是,當你知道ChainMap存在的時候,ChainMap可以讓你更輕鬆,你的代碼更優雅。


事實上,我第一次使用ChainMap是在一周前。為什麼以前沒有呢?我根本沒用過。


我使用它是因為我需要頻繁地計算字典的子集(基於值的屬性),這代價很大。我需要實現

恆定的時間查找

以滿足性能要求。


我決定把字典分成兩個不同的dict,並在插入時執行分支。然後我用ChainMap把這兩個dict組合在一起。這樣,我就可以在單個字典中保留最初的視圖——但也可以在固定時間內查找每個單獨的字典。


總結


總而言之,我們一起看了ChainMap是什麼,一些具體的使用示例,以及如何在現實生活中,性能關鍵的應用程序中使用ChainMap。


如果您想了解更多關於Python的高性能數據容器的信息,請務必從Python的標準庫中collections模塊中查看其他出色類和函數。




英文原文:https://blog.florimondmanca.com/a-practical-usage-of-chainmap-in-python


譯者:張新英



喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 Python程序員 的精彩文章:

如何治癒在Stack Overflow上受到的創傷?
PyQt5教程 --學習如何創建一個2018年的Python GUI

TAG:Python程序員 |