目錄
學習目標
為什麼要使用namedtuple
如何將常規元組或字典轉換為 namedtuple
如何将 namedtuple 转换为字典或常规元组
如何对namedtuples列表进行排序
如何将namedtuples序列化为JSON
如何给namedtuple添加docstring
首頁 後端開發 Python教學 Python資料結構:一個被低估的Namedtuple(一)

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

Oct 19, 2020 pm 05:45 PM
python

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'复制代码
登入後複製

不僅如此,現在我們可以使用它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中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱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

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

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

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

PHP和Python:解釋了不同的範例 PHP和Python:解釋了不同的範例 Apr 18, 2025 am 12:26 AM

PHP主要是過程式編程,但也支持面向對象編程(OOP);Python支持多種範式,包括OOP、函數式和過程式編程。 PHP適合web開發,Python適用於多種應用,如數據分析和機器學習。

在PHP和Python之間進行選擇:指南 在PHP和Python之間進行選擇:指南 Apr 18, 2025 am 12:24 AM

PHP適合網頁開發和快速原型開發,Python適用於數據科學和機器學習。 1.PHP用於動態網頁開發,語法簡單,適合快速開發。 2.Python語法簡潔,適用於多領域,庫生態系統強大。

PHP和Python:深入了解他們的歷史 PHP和Python:深入了解他們的歷史 Apr 18, 2025 am 12:25 AM

PHP起源於1994年,由RasmusLerdorf開發,最初用於跟踪網站訪問者,逐漸演變為服務器端腳本語言,廣泛應用於網頁開發。 Python由GuidovanRossum於1980年代末開發,1991年首次發布,強調代碼可讀性和簡潔性,適用於科學計算、數據分析等領域。

Python vs. JavaScript:學習曲線和易用性 Python vs. JavaScript:學習曲線和易用性 Apr 16, 2025 am 12:12 AM

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。

vs code 可以在 Windows 8 中運行嗎 vs code 可以在 Windows 8 中運行嗎 Apr 15, 2025 pm 07:24 PM

VS Code可以在Windows 8上運行,但體驗可能不佳。首先確保系統已更新到最新補丁,然後下載與系統架構匹配的VS Code安裝包,按照提示安裝。安裝後,注意某些擴展程序可能與Windows 8不兼容,需要尋找替代擴展或在虛擬機中使用更新的Windows系統。安裝必要的擴展,檢查是否正常工作。儘管VS Code在Windows 8上可行,但建議升級到更新的Windows系統以獲得更好的開發體驗和安全保障。

sublime怎麼運行代碼python sublime怎麼運行代碼python Apr 16, 2025 am 08:48 AM

在 Sublime Text 中運行 Python 代碼,需先安裝 Python 插件,再創建 .py 文件並編寫代碼,最後按 Ctrl B 運行代碼,輸出會在控制台中顯示。

visual studio code 可以用於 python 嗎 visual studio code 可以用於 python 嗎 Apr 15, 2025 pm 08:18 PM

VS Code 可用於編寫 Python,並提供許多功能,使其成為開發 Python 應用程序的理想工具。它允許用戶:安裝 Python 擴展,以獲得代碼補全、語法高亮和調試等功能。使用調試器逐步跟踪代碼,查找和修復錯誤。集成 Git,進行版本控制。使用代碼格式化工具,保持代碼一致性。使用 Linting 工具,提前發現潛在問題。

notepad 怎麼運行python notepad 怎麼運行python Apr 16, 2025 pm 07:33 PM

在 Notepad 中運行 Python 代碼需要安裝 Python 可執行文件和 NppExec 插件。安裝 Python 並為其添加 PATH 後,在 NppExec 插件中配置命令為“python”、參數為“{CURRENT_DIRECTORY}{FILE_NAME}”,即可在 Notepad 中通過快捷鍵“F6”運行 Python 代碼。

See all articles