搜尋
首頁後端開發Python教學Python資料結構:一個被低估的Namedtuple(一)

Python教學欄位為大家介紹Python資料結構中的Namedtuple。

Python資料結構:一個被低估的Namedtuple(一)

本文將討論python中namedtuple的重點用法。我們將由淺入深的介紹namedtuple的各概念。您將了解為什麼要使用它們,以及如何使用它們,從而是程式碼更簡潔。在學習本指南之後,你一定會喜歡上使用它。

學習目標

在本教學結束時,您應該能夠:

  • #了解為什麼以及何時使用它
  • 將常規元組和字典轉換為Namedtuple
  • Namedtuple轉換為字典或常規元組
  • Namedtuple列表進行排序
  • 了解Namedtuple和資料類別(DataClass)之間的差異
  • #使用可選欄位建立Namedtuple
  • Namedtuple序列化為JSON
  • 新增文件字串(docstring)

為什麼要使用namedtuple

namedtuple是一個非常有趣(也被低估了)的資料結構。我們可以輕鬆找到嚴重依賴常規元組和字典來儲存資料的Python程式碼。我並不是說,這樣不好,只是有時候他們常常被濫用,而且聽我慢慢道來。

假設你有一個將字串轉換為顏色的函數。顏色必須在4維空間RGBA中表示。

def convert_string_to_color(desc: str, alpha: float = 0.0):
    if desc == "green":        return 50, 205, 50, alpha    elif desc == "blue":        return 0, 0, 255, alpha    else:        return 0, 0, 0, alpha复制代码

然後,我們可以像這樣使用它:

r, g, b, a = convert_string_to_color(desc="blue", alpha=1.0)复制代码

好的,可以。但是我們這裡有幾個問題。第一個是,無法確保回傳值的順序。也就是說,沒有什麼可以阻止其他開發者這樣呼叫

convert_string_to_color:
g, b, r, a = convert_string_to_color(desc="blue", alpha=1.0)复制代码

另外,我們可能不知道該函數傳回4個值,可能會這樣呼叫該函數:

r, g, b = convert_string_to_color(desc="blue", alpha=1.0)复制代码

於是,因為回傳值不夠,拋出ValueError錯誤,呼叫失敗。

確實如此。但是,你可能會問,為什麼不使用字典呢?

Python的字典是一種非常通用的資料結構。它們是一種儲存多個值的簡單方法。但是,字典並非沒有缺點。由於其靈活性,字典很容易被濫用。讓 讓我們來看看使用字典之後的例子。

def convert_string_to_color(desc: str, alpha: float = 0.0):
    if desc == "green":        return {"r": 50, "g": 205, "b": 50, "alpha": alpha}    elif desc == "blue":        return {"r": 0, "g": 0, "b": 255, "alpha": alpha}    else:        return {"r": 0, "g": 0, "b": 0, "alpha": alpha}复制代码

好的,我們現在可以像這樣使用它,期望只回傳一個值:

color = convert_string_to_color(desc="blue", alpha=1.0)复制代码

無需記住順序,但它至少有兩個缺點。第一個是我們必須追蹤密鑰的名稱。如果我們將其更改{"r": 0, “g”: 0, “b”: 0, “alpha”: alpha}{”red": 0, “green” : 0, “blue”: 0, “a”: alpha},則在存取欄位時會得到KeyError返回,因為鍵r,g,balpha不再存在。

字典的第二個問題是它們不可散列。這意味著我們無法將它們儲存在set或其他字典中。假設我們要追蹤特定圖像有多少種顏色。如果我們使用collections.Counter計數,我們將得到TypeError: unhashable type: ‘dict’

而且,字典是可變的,因此我們可以根據需要添加任意數量的新鍵。相信我,這是一些很難發現的令人討厭的錯誤點。

好的,很好。那現在怎麼辦?我可以用什麼代替呢?

namedtuple!對,就是它!

將我們的函數轉換為使用namedtuple

from collections import namedtuple
...
Color = namedtuple("Color", "r g b alpha")
...def convert_string_to_color(desc: str, alpha: float = 0.0):
    if desc == "green":        return Color(r=50, g=205, b=50, alpha=alpha)    elif desc == "blue":        return Color(r=50, g=0, b=255, alpha=alpha)    else:        return Color(r=50, g=0, b=0, alpha=alpha)复制代码

與dict的情況一樣,我們可以將值指派給單一變數並根據需要使用。無需記住順序。而且,如果你使用的是諸如PyCharm和VSCode之類的IDE ,還可以自動提示補全。

color = convert_string_to_color(desc="blue", alpha=1.0)
...
has_alpha = color.alpha > 0.0...
is_black = color.r == 0 and color.g == 0 and color.b == 0复制代码

最重要的是namedtuple是不可變的。如果團隊中的另一位開發人員認為在運行時新增欄位是個好主意,則該程式將報錯。

>>> blue = Color(r=0, g=0, b=255, alpha=1.0)>>> blue.e = 0---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-13-8c7f9b29c633> in <module>
----> 1 blue.e = 0AttributeError: 'Color' object has no attribute 'e'复制代码</module></ipython-input-13-8c7f9b29c633>

不僅如此,現在我們可以使用它Counter來追蹤一個集合有多少種顏色。

>>> Counter([blue, blue])>>> Counter({Color(r=0, g=0, b=255, alpha=1.0): 2})复制代码

如何將常規元組或字典轉換為 namedtuple

現在我們了解了為什麼使用namedtuple,現在該學習如何將常規元組和字典轉換為namedtuple了。假設由於某些原因,你有一個包含彩色RGBA值的字典實例。如果要將其轉換為Color namedtuple,則可以按以下步驟進行:

>>> c = {"r": 50, "g": 205, "b": 50, "alpha": alpha}>>> Color(**c)>>> Color(r=50, g=205, b=50, alpha=0)复制代码

我們可以利用該**結構將套件解壓縮dict namedtuple

如果我想從dict建立一個namedtupe,如何做?

沒問題,下面這樣做就可以了:

>>> c = {"r": 50, "g": 205, "b": 50, "alpha": alpha}>>> Color = namedtuple("Color", c)>>> Color(**c)
Color(r=50, g=205, b=50, alpha=0)复制代码

透過將dict實例傳遞給namedtuple工廠函數,它將為你建立欄位。然後,Color像上邊的例子一樣解壓縮字典c,並建立新實例。

如何将 namedtuple 转换为字典或常规元组

我们刚刚学习了如何将转换namedtupledict。反过来呢?我们又如何将其转换为字典实例?

实验证明,namedtuple它带有一种称为的方法._asdict()。因此,转换它就像调用方法一样简单。

>>> blue = Color(r=0, g=0, b=255, alpha=1.0)>>> blue._asdict()
{'r': 0, 'g': 0, 'b': 255, 'alpha': 1.0}复制代码

您可能想知道为什么该方法以_开头。这是与Python的常规规范不一致的一个地方。通常,_代表私有方法或属性。但是,namedtuple为了避免命名冲突将它们添加到了公共方法中。除了_asdict,还有_replace_fields_field_defaults。您可以在这里找到所有这些。

要将namedtupe转换为常规元组,只需将其传递给tuple构造函数即可。

>>> tuple(Color(r=50, g=205, b=50, alpha=0.1))
(50, 205, 50, 0.1)复制代码

如何对namedtuples列表进行排序

另一个常见的用例是将多个namedtuple实例存储在列表中,并根据某些条件对它们进行排序。例如,假设我们有一个颜色列表,我们需要按alpha强度对其进行排序。

幸运的是,Python允许使用非常Python化的方式来执行此操作。我们可以使用operator.attrgetter运算符。根据文档,attrgetter“返回从其操作数获取attr的可调用对象”。简单来说就是,我们可以通过该运算符,来获取传递给sorted函数排序的字段。例:

from operator import attrgetter
...
colors = [
    Color(r=50, g=205, b=50, alpha=0.1),
    Color(r=50, g=205, b=50, alpha=0.5),
    Color(r=50, g=0, b=0, alpha=0.3)
]
...>>> sorted(colors, key=attrgetter("alpha"))
[Color(r=50, g=205, b=50, alpha=0.1),
 Color(r=50, g=0, b=0, alpha=0.3),
 Color(r=50, g=205, b=50, alpha=0.5)]复制代码

现在,颜色列表按alpha强度升序排列!

如何将namedtuples序列化为JSON

有时你可能需要将储存namedtuple转为JSON。Python的字典可以通过json模块转换为JSON。那么我们可以使用_asdict方法将元组转换为字典,然后接下来就和字典一样了。例如:

>>> blue = Color(r=0, g=0, b=255, alpha=1.0)>>> import json>>> json.dumps(blue._asdict())'{"r": 0, "g": 0, "b": 255, "alpha": 1.0}'复制代码

如何给namedtuple添加docstring

在Python中,我们可以使用纯字符串来记录方法,类和模块。然后,此字符串可作为名为的特殊属性使用__doc__。话虽这么说,我们如何向我们的Color namedtuple添加docstring的?

我们可以通过两种方式做到这一点。第一个(比较麻烦)是使用包装器扩展元组。这样,我们便可以docstring在此包装器中定义。例如,请考虑以下代码片段:

_Color = namedtuple("Color", "r g b alpha")

class Color(_Color):
    """A namedtuple that represents a color.
    It has 4 fields:
    r - red
    g - green
    b - blue
    alpha - the alpha channel
    """

>>> print(Color.__doc__)
A namedtuple that represents a color.
    It has 4 fields:
    r - red
    g - green
    b - blue
    alpha - the alpha channel
>>> help(Color)
Help on class Color in module __main__:

class Color(Color)
 |  Color(r, g, b, alpha)
 |  
 |  A namedtuple that represents a color.
 |  It has 4 fields:
 |  r - red
 |  g - green
 |  b - blue
 |  alpha - the alpha channel
 |  
 |  Method resolution order:
 |      Color
 |      Color
 |      builtins.tuple
 |      builtins.object
 |  
 |  Data descriptors defined here:
 |  
 |  __dict__
 |      dictionary for instance variables (if defined)复制代码

如上,通过继承_Color元组,我们为namedtupe添加了一个__doc__属性。

添加的第二种方法,直接设置__doc__属性。这种方法不需要扩展元组。

>>> Color.__doc__ = """A namedtuple that represents a color.
    It has 4 fields:
    r - red
    g - green
    b - blue
    alpha - the alpha channel
    """复制代码

注意,这些方法仅适用于Python 3+

限于篇幅,先到这下篇继续。

相关免费学习推荐:python教程(视频)

以上是Python資料結構:一個被低估的Namedtuple(一)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:juejin。如有侵權,請聯絡admin@php.cn刪除
Python的科學計算中如何使用陣列?Python的科學計算中如何使用陣列?Apr 25, 2025 am 12:28 AM

Arraysinpython,尤其是Vianumpy,ArecrucialInsCientificComputingfortheireftheireffertheireffertheirefferthe.1)Heasuedfornumerericalicerationalation,dataAnalysis和Machinelearning.2)Numpy'Simpy'Simpy'simplementIncressionSressirestrionsfasteroperoperoperationspasterationspasterationspasterationspasterationspasterationsthanpythonlists.3)inthanypythonlists.3)andAreseNableAblequick

您如何處理同一系統上的不同Python版本?您如何處理同一系統上的不同Python版本?Apr 25, 2025 am 12:24 AM

你可以通過使用pyenv、venv和Anaconda來管理不同的Python版本。 1)使用pyenv管理多個Python版本:安裝pyenv,設置全局和本地版本。 2)使用venv創建虛擬環境以隔離項目依賴。 3)使用Anaconda管理數據科學項目中的Python版本。 4)保留系統Python用於系統級任務。通過這些工具和策略,你可以有效地管理不同版本的Python,確保項目順利運行。

與標準Python陣列相比,使用Numpy數組的一些優點是什麼?與標準Python陣列相比,使用Numpy數組的一些優點是什麼?Apr 25, 2025 am 12:21 AM

numpyarrayshaveseveraladagesoverandastardandpythonarrays:1)基於基於duetoc的iMplation,2)2)他們的aremoremoremorymorymoremorymoremorymoremorymoremoremory,尤其是WithlargedAtasets和3)效率化,效率化,矢量化函數函數函數函數構成和穩定性構成和穩定性的操作,製造

陣列的同質性質如何影響性能?陣列的同質性質如何影響性能?Apr 25, 2025 am 12:13 AM

數組的同質性對性能的影響是雙重的:1)同質性允許編譯器優化內存訪問,提高性能;2)但限制了類型多樣性,可能導致效率低下。總之,選擇合適的數據結構至關重要。

編寫可執行python腳本的最佳實踐是什麼?編寫可執行python腳本的最佳實踐是什麼?Apr 25, 2025 am 12:11 AM

到CraftCraftExecutablePythcripts,lollow TheSebestPractices:1)Addashebangline(#!/usr/usr/bin/envpython3)tomakethescriptexecutable.2)setpermissionswithchmodwithchmod xyour_script.3)

Numpy數組與使用數組模塊創建的數組有何不同?Numpy數組與使用數組模塊創建的數組有何不同?Apr 24, 2025 pm 03:53 PM

numpyArraysareAreBetterFornumericalialoperations andmulti-demensionaldata,而learthearrayModuleSutableforbasic,內存效率段

Numpy數組的使用與使用Python中的數組模塊陣列相比如何?Numpy數組的使用與使用Python中的數組模塊陣列相比如何?Apr 24, 2025 pm 03:49 PM

numpyArraySareAreBetterForHeAvyNumericalComputing,而lelethearRayModulesiutable-usemoblemory-connerage-inderabledsswithSimpleDatateTypes.1)NumpyArsofferVerverVerverVerverVersAtility andPerformanceForlargedForlargedAtatasetSetsAtsAndAtasEndCompleXoper.2)

CTYPES模塊與Python中的數組有何關係?CTYPES模塊與Python中的數組有何關係?Apr 24, 2025 pm 03:45 PM

ctypesallowscreatingingangandmanipulatingc-stylarraysinpython.1)usectypestoInterfacewithClibrariesForperfermance.2)createc-stylec-stylec-stylarraysfornumericalcomputations.3)passarraystocfunctions foreforfunctionsforeffortions.however.however,However,HoweverofiousofmemoryManageManiverage,Pressiveo,Pressivero

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

WebStorm Mac版

WebStorm Mac版

好用的JavaScript開發工具

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)