如何在 Python 中建立一個不可變的字典 - Adam Johnson
Python 的內建集合型別具有可變和不可變兩種風格:
- 可變版本:list 不可變版本:tuple
- 可變版本:set 不可變版本:frozenset
- 可變版本:dict 不可變版本:MappingProxyType
PEP 416早在 2012 年就為 Python 3.3提出了一種型別frozendict。 PEP 被拒絕,原因有很多。推理包括幾個關於不可變 dict 的效用的問題,在將它們新增到程式碼之前值得檢查一下。
但是 PEP確實為我們提供了一個模擬不可變dicts:的工具types.MappingProxyType。此型別是 adict或其他對映的只讀代理。Python 在內部將這種型別用於重要的詞典,這就是為什麼您不能隨意修補內建型別的原因。
Python 3.3 中唯一的變化是為使用者程式碼公開這種型別。
要建立一個“不可變”的字典,MappingProxyType從字典中建立一個,而不保留對底層字典的任何引用:
from types import MappingProxyType power_levels = MappingProxyType( { "Kevin": 9001, "Benny": 8000, } ) 讀取: In [1]: power_levels["Kevin"] Out[1]: 9001 In [2]: power_levels["Benny"] Out[2]: 8000 In [3]: list(power_levels.keys()) Out[3]: ['Kevin', 'Benny'] |
但是,任何更改值的嘗試都將導致TypeError:
In [4]: power_levels["Benny"] = 9200 --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-4-39fccb3e4f76> in <module> ----> 1 power_levels["Benny"] = 9200 TypeError: 'mappingproxy' object does not support item assignment |
要使用更改建立對映代理的副本,您可以使用 Python 3.9 的dict 合併運算子。將對映代理與新字典合併,並將結果傳遞給MappingProxyType
In [10]: benny_better = MappingProxyType(power_levels | {"Benny": 9200}) In [11]: benny_better Out[11]: mappingproxy({'Kevin': 9001, 'Benny': 9200}) |
對於更復雜的修改,您可以將對映代理複製到新的dict進行更改,然後將結果轉換為對映代理:
In [12]: new_world = power_levels | {} In [13]: del new_world["Benny"] In [14]: del new_world["Kevin"] In [15]: new_world["Bock"] = 100 In [16]: new_world = MappingProxyType(new_world) In [17]: new_world Out[17]: mappingproxy({'Bock': 100}) |
有幾個提供不可變資料結構的第三方包,例如immutables和pyrsistent。這些 API 稍微好一些,但會帶來不同的權衡,例如效能和維護狀態。如果MappingProxyType不適合您,您可能想研究它們,但我鼓勵儘可能多地使用標準庫。
相關文章
- Java中建立不可變的類Java
- Python中的不可變集合Python
- 給出 Python 中變數名的列表,如何建立一個具有變數名稱作為鍵的字典 (到變數的值)Python變數
- Java中如何快捷的建立不可變集合Java
- python建立字典Python
- Python中的字典Python
- Python中可變物件和不可變物件的區別?Python基礎Python物件
- Python實現建立字典Python
- python2.7中複製資料模型(可變與不可變模型)的幾個坑Python模型
- 什麼是字典?Python字典是可變的嗎?Python
- Python建立字典與fromkeys的坑Python
- python中的引用傳遞,可變物件,不可變物件,list注意點Python物件
- Java中的不可變集合,我們換個方式理解!!!Java
- Python - 可變和不可變物件Python物件
- 在Python中將字典轉為成員變數的方法Python變數
- Python中遍歷字典以及字典中的鍵和值Python
- python中的集合與字典Python
- python中的字典學習Python
- Python中的列表、元祖、字典Python
- Python可變物件和不可變物件Python物件
- Python基礎(一)可變與不可變資料型別Python資料型別
- python-字典-如何取出字典中的所有值Python
- python技巧 使用值來排序一個字典Python排序
- 如何在 GitHub 建立一個“有人用”的專案Github
- 如何在 Flutter 建立一個後臺任務Flutter
- 如何在Github上建立一個新倉庫Github
- python中的字典是什麼Python
- 深入探究Python中的字典容器Python
- Python 字串不可變性的優缺點Python字串
- 如何在 LibreOffice Writer 中建立一個電子書章節模板
- Java中的不可變資料結構Java資料結構
- 深入理解Java中的不可變物件Java物件
- Python 字典中一鍵對應多個值Python
- Python 元組,不可變的列表,滾雪球學 PythonPython
- Java中實現不可變MapJava
- java 中構建不可變物件Java物件
- 【不可思議的前端】動如脫兔的小球前端
- 如何在 Fedora 上建立一個 TFTP 伺服器FTP伺服器