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
譯者:張新英


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