摘要:上一篇文章標準庫內置類型數字類型下一篇文章標準庫內置類型文本序列類型迭代器類型支持在容器中進行迭代的概念。該對象需要支持下文所述的迭代器協議。這是同時允許容器和迭代器配合和語句使用所必須的。
上一篇文章:Python標準庫---10、內置類型:數字類型
下一篇文章:Python標準庫---12、內置類型:文本序列類型(str)
## 迭代器類型
Python 支持在容器中進行迭代的概念。 這是通過使用兩個多帶帶方法來實現的;它們被用于允許用戶自定義類對迭代的支持。 將在下文中詳細描述的序列總是支持迭代方法。
容器對象要提供迭代支持,必須定義一個方法:
container.__iter__()返回一個迭代器對象。 該對象需要支持下文所述的迭代器協議。 如果容器支持不同的迭代類型,則可以提供額外的方法來專門地請求不同迭代類型的迭代器。 (支持多種迭代形式的對象的例子有同時支持廣度優先和深度優先遍歷的樹結構。) 此方法對應于 Python/C API 中 Python 對象類型結構體的 tp_iter 槽位。
迭代器對象自身需要支持以下兩個方法,它們共同組成了 迭代器協議:
iterator.__iter__()返回迭代器對象本身。 這是同時允許容器和迭代器配合 for 和 in 語句使用所必須的。 此方法對應于 Python/C API 中 Python 對象類型結構體的 tp_iter 槽位。
iterator.__next__()從容器中返回下一項。 如果已經沒有項可返回,則會引發 StopIteration 異常。 此方法對應于 Python/C API 中 Python 對象類型結構體的 tp_iternext 槽位。
Python 定義了幾種迭代器對象以支持對一般和特定序列類型、字典和其他更特別的形式進行迭代。 除了迭代器協議的實現,特定類型的其他性質對迭代操作來說都不重要。
一旦迭代器的 __next__() 方法引發了 StopIteration,它必須一直對后續調用引發同樣的異常。 不遵循此行為特性的實現將無法正常使用。
生成器類型Python 的 generator 提供了一種實現迭代器協議的便捷方式。 如果容器對象 __iter__() 方法被實現為一個生成器,它將自動返回一個迭代器對象(從技術上說是一個生成器對象),該對象提供 __iter__() 和 __next__() 方法。 有關生成器的更多信息可以參閱 yield 表達式的文檔。
序列類型 --- list, tuple, range有三種基本序列類型:list, tuple 和 range 對象。 為處理 二進制數據 和 文本字符串 而特別定制的附加序列類型會在專門的小節中描述。
通用序列操作大多數序列類型,包括可變類型和不可變類型都支持下表中的操作。 collections.abc.Sequence ABC 被提供用來更容易地在自定義序列類型上正確地實現這些操作。
此表按優先級升序列出了序列操作。 在表格中,s 和 t 是具有相同類型的序列,n, i, j 和 k 是整數,而 x 是任何滿足 s 所規定的類型和值限制的任意對象。
in 和 not in 操作具有與比較操作相同的優先級。 + (拼接) 和 * (重復) 操作具有與對應數值運算相同的優先級。
相同類型的序列也支持比較。 特別地,tuple 和 list 的比較是通過比較對應元素的字典順序。 這意味著想要比較結果相等,則每個元素比較結果都必須相等,并且兩個序列長度必須相同。 (完整細節請參閱語言參考的 比較運算 部分。)
注釋:
雖然 in 和 not in 操作在通常情況下僅被用于簡單的成員檢測,某些專門化序列 (例如 str, bytes 和 bytearray) 也使用它們進行子序列檢測:
>>> >>> "gg" in "eggs" True
小于 0 的 n 值會被當作 0 來處理 (生成一個與 s 同類型的空序列)。
請注意序列 s 中的項并不會被拷貝;它們會被多次引用。 這一點經常會令 Python 編程新手感到困擾;例如:
>>> >>> lists = [[]] * 3 >>> lists [[], [], []] >>> lists[0].append(3) >>> lists [[3], [3], [3]]
具體的原因在于 [[]] 是一個包含了一個空列表的單元素列表,所以 [[]] * 3 結果中的三個元素都是對這一個空列表的引用。 修改 lists 中的任何一個元素實際上都是對這一個空列表的修改。 你可以用以下方式創建以不同列表為元素的列表:
>>> >>> lists = [[] for i in range(3)] >>> lists[0].append(3) >>> lists[1].append(5) >>> lists[2].append(7) >>> lists [[3], [5], [7]] 進一步的解釋可以在 FAQ 條目 如何創建多維列表? 中查看。
如果 i 或 j 為負值,則索引順序是相對于序列 s 的末尾: 索引號會被替換為 len(s) + i 或 len(s) + j。 但要注意 -0 仍然為 0。
s 從 i 到 j 的切片被定義為所有滿足 i <= k < j 的索引號 k 的項組成的序列。 如果 i 或 j 大于 len(s),則使用 len(s)。 如果 i 被省略或為 None,則使用 0。 如果 j 被省略或為 None,則使用 len(s)。 如果 i 大于等于 j,則切片為空。
s 從 i 到 j 步長為 k 的切片被定義為所有滿足 0 <= n < (j-i)/k 的索引號 x = i + nk 的項組成的序列。 換句話說,索引號為 i, i+k, i+2k, i+3*k,以此類推,當達到 j 時停止 (但一定不包括 j)。 當 k 為正值時,i 和 j 會被減至不大于 len(s)。 當 k 為負值時,i 和 j 會被減至不大于 len(s) - 1。 如果 i 或 j 被省略或為 None,它們會成為“終止”值 (是哪一端的終止值則取決于 k 的符號)。 請注意,k 不可為零。 如果 k 為 None,則當作 1 處理。
拼接不可變序列總是會生成新的對象。 這意味著通過重復拼接來構建序列的運行時開銷將會基于序列總長度的乘方。 想要獲得線性的運行時開銷,你必須改用下列替代方案之一:
如果拼接 str 對象,你可以構建一個列表并在最后使用 str.join() 或是寫入一個 io.StringIO 實例并在結束時獲取它的值
如果拼接 bytes 對象,你可以類似地使用 bytes.join() 或 io.BytesIO,或者你也可以使用 bytearray 對象進行原地拼接。 bytearray 對象是可變的,并且具有高效的重分配機制
如果拼接 tuple 對象,請改為擴展 list 類
對于其它類型,請查看相應的文檔
某些序列類型 (例如 range) 僅支持遵循特定模式的項序列,因此并不支持序列拼接或重復。
當 x 在 s 中找不到時 index 會引發 ValueError。 不是所有實現都支持傳入額外參數 i 和 j。 這兩個參數允許高效地搜索序列的子序列。 傳入這兩個額外參數大致相當于使用 s[i:j].index(x),但是不會復制任何數據,并且返回的索引是相對于序列的開頭而非切片的開頭。
不可變序列類型不可變序列類型普遍實現而可變序列類型未實現的唯一操作就是對 hash() 內置函數的支持。
這種支持允許不可變類型,例如 tuple 實例被用作 dict 鍵,以及存儲在 set 和 frozenset 實例中。
嘗試對包含有不可哈希值的不可變序列進行哈希運算將會導致 TypeError。
可變序列類型以下表格中的操作是在可變序列類型上定義的。 collections.abc.MutableSequence ABC 被提供用來更容易地在自定義序列類型上正確實現這些操作。
表格中的 s 是可變序列類型的實例,t 是任意可迭代對象,而 x 是符合對 s 所規定類型與值限制的任何對象 (例如,bytearray 僅接受滿足 0 <= x <= 255 值限制的整數)。
注釋:
t 必須與它所替換的切片具有相同的長度。
可選參數 i 默認為 -1,因此在默認情況下會移除并返回最后一項。
當在 s 中找不到 x 時 remove 操作會引發 ValueError。
當反轉大尺寸序列時 reverse() 方法會原地修改該序列以保證空間經濟性。 為提醒用戶此操作是通過間接影響進行的,它并不會返回反轉后的序列。
包括 clear() 和 copy() 是為了與不支持切片操作的可變容器 (例如 dict 和 set) 的接口保持一致
3.3 新版功能: clear() 和 copy() 方法。
n 值為一個整數,或是一個實現了 __index__() 的對象。 n 值為零或負數將清空序列。 序列中的項不會被拷貝;它們會被多次引用,正如 通用序列操作 中有關 s * n 的說明。
列表列表是可變序列,通常用于存放同類項目的集合(其中精確的相似程度將根據應用而變化)。
class list([iterable])可以用多種方式構建列表:
使用一對方括號來表示空列表: []
使用方括號,其中的項以逗號分隔: [a], [a, b, c]
使用列表推導式: [x for x in iterable]
使用類型的構造器: list() 或 list(iterable)
構造器將構造一個列表,其中的項與 iterable 中的項具有相同的的值與順序。 iterable 可以是序列、支持迭代的容器或其它可迭代對象。 如果 iterable 已經是一個列表,將創建并返回其副本,類似于 iterable[:]。 例如,list("abc") 返回 ["a", "b", "c"] 而 list( (1, 2, 3) ) 返回 [1, 2, 3]。 如果沒有給出參數,構造器將創建一個空列表 []。
其它許多操作也會產生列表,包括 sorted() 內置函數。
列表實現了所有 一般 和 可變 序列的操作。 列表還額外提供了以下方法:
#### sort(*, key=None, reverse=False)
此方法會對列表進行原地排序,只使用 < 來進行各項間比較。 異常不會被屏蔽 —— 如果有任何比較操作失敗,整個排序操作將失敗(而列表可能會處于被部分修改的狀態)。
sort() 接受兩個僅限以關鍵字形式傳入的參數 (僅限關鍵字參數):
key 指定帶有一個參數的函數,用于從每個列表元素中提取比較鍵 (例如 key=str.lower)。 對應于列表中每一項的鍵會被計算一次,然后在整個排序過程中使用。 默認值 None 表示直接對列表項排序而不計算一個多帶帶的鍵值。
可以使用 functools.cmp_to_key() 將 2.x 風格的 cmp 函數轉換為 key 函數。
reverse 為一個布爾值。 如果設為 True,則每個列表元素將按反向順序比較進行排序。
當順序大尺寸序列時此方法會原地修改該序列以保證空間經濟性。 為提醒用戶此操作是通過間接影響進行的,它并不會返回排序后的序列(請使用 sorted() 顯示地請求一個新的已排序列表實例)。
sort() 方法確保是穩定的。 如果一個排序確保不會改變比較結果相等的元素的相對順序就稱其為穩定的 --- 這有利于進行多重排序(例如先按部門、再接薪級排序)。
CPython implementation detail: 在一個列表被排序期間,嘗試改變甚至進行檢測也會造成未定義的影響。 Python 的 C 實現會在排序期間將列表顯示為空,如果發現列表在排序期間被改變將會引發 ValueError。
元組元組是不可變序列,通常用于儲存異構數據的多項集(例如由 enumerate() 內置函數所產生的二元組)。 元組也被用于需要同構數據的不可變序列的情況(例如允許存儲到 set 或 dict 的實例)。
class tuple([iterable])可以用多種方式構建元組:
使用一對圓括號來表示空元組: ()
使用一個后綴的逗號來表示單元組: a, 或 (a,)
使用以逗號分隔的多個項: a, b, c or (a, b, c)
使用內置的 tuple(): tuple() 或 tuple(iterable)
構造器將構造一個元組,其中的項與 iterable 中的項具有相同的值與順序。 iterable 可以是序列、支持迭代的容器或其他可迭代對象。 如果 iterable 已經是一個元組,會不加改變地將其返回。 例如,tuple("abc") 返回 ("a", "b", "c") 而 tuple( [1, 2, 3] ) 返回 (1, 2, 3)。 如果沒有給出參數,構造器將創建一個空元組 ()。
請注意決定生成元組的其實是逗號而不是圓括號。 圓括號只是可選的,生成空元組或需要避免語法歧義的情況除外。 例如,f(a, b, c) 是在調用函數時附帶三個參數,而 f((a, b, c)) 則是在調用函數時附帶一個三元組。
元組實現了所有 一般 序列的操作。
對于通過名稱訪問相比通過索引訪問更清晰的異構數據多項集,collections.namedtuple() 可能是比簡單元組對象更為合適的選擇。
range 對象range 類型表示不可變的數字序列,通常用于在 for 循環中循環指定的次數。
class range(stop) class range(start, stop[, step])range 構造器的參數必須為整數(可以是內置的 int 或任何實現了 __index__ 特殊方法的對象)。 如果省略 step 參數,其默認值為 1。 如果省略 start 參數,其默認值為 0,如果 step 為零則會引發 ValueError。 如果 step 為正值,確定 range r 內容的公式為 r[i] = start + step*i 其中 i >= 0 且 r[i] < stop。 如果 step 為負值,確定 range 內容的公式仍然為 r[i] = start + step*i,但限制條件改為 i >= 0 且 r[i] > stop. 如果 r[0] 不符合值的限制條件,則該 range 對象為空。 range 對象確實支持負索引,但是會將其解讀為從正索引所確定的序列的末尾開始索引。 元素絕對值大于 sys.maxsize 的 range 對象是被允許的,但某些特性 (例如 len()) 可能引發 OverflowError。 一些 range 對象的例子:
>>> list(range(10)) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> list(range(1, 11)) [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] >>> list(range(0, 30, 5)) [0, 5, 10, 15, 20, 25] >>> list(range(0, 10, 3)) [0, 3, 6, 9] >>> list(range(0, -10, -1)) [0, -1, -2, -3, -4, -5, -6, -7, -8, -9] >>> list(range(0)) [] >>> list(range(1, 0)) []
range 對象實現了 一般 序列的所有操作,但拼接和重復除外(這是由于 range 對象只能表示符合嚴格模式的序列,而重復和拼接通常都會違反這樣的模式)。 start start 形參的值 (如果該形參未提供則為 0) stop stop 形參的值 step step 形參的值 (如果該形參未提供則為 1)
range 類型相比常規 list 或 tuple 的優勢在于一個 range 對象總是占用固定數量的(較小)內存,不論其所表示的范圍有多大(因為它只保存了 start, stop 和 step 值,并會根據需要計算具體單項或子范圍的值)。
range 對象實現了 collections.abc.Sequence ABC,提供如包含檢測、元素索引查找、切片等特性,并支持負索引 (參見 序列類型 --- list, tuple, range):
>>> r = range(0, 20, 2) >>> r range(0, 20, 2) >>> 11 in r False >>> 10 in r True >>> r.index(10) 5 >>> r[5] 10 >>> r[:5] range(0, 10, 2) >>> r[-1] 18
使用 == 和 != 檢測 range 對象是否相等是將其作為序列來比較。 也就是說,如果兩個 range 對象表示相同的值序列就認為它們是相等的。 (請注意比較結果相等的兩個 range 對象可能會具有不同的 start, stop 和 step 屬性,例如 range(0) == range(2, 1, 3) 而 range(0, 3, 2) == range(0, 4, 2)。)
在 3.2 版更改: 實現 Sequence ABC。 支持切片和負數索引。 使用 int 對象在固定時間內進行成員檢測,而不是逐一迭代所有項。
在 3.3 版更改: 定義 "==" 和 "!=" 以根據 range 對象所定義的值序列來進行比較(而不是根據對象的標識)。
3.3 新版功能: start, stop 和 step 屬性。
參見
linspace recipe 演示了如何實現一個延遲求值版本的適合浮點數應用的 range 對象。
上一篇文章:Python標準庫---10、內置類型:數字類型
下一篇文章:Python標準庫---12、內置類型:文本序列類型(str)
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/43975.html
摘要:上一篇文章標準庫內置類型迭代器類型序列類型下一篇文章標準庫內置類型二進制序列類型文本序列類型在中處理文本數據是使用對象,也稱為字符串。正式的定義為十進制數字符就是一般分類中的字符。 上一篇文章:Python標準庫---11、內置類型:迭代器類型、序列類型(list-typle-range)下一篇文章:Python標準庫---13、內置類型:二進制序列類型 ( bytes, bytear...
摘要:標準庫一譯廖雪峰內建函數內建函數內建函數內置類型真值的測試下面的值被視為假任何數值類型的零,例如,。該對象必須支持如下所述的迭代器協議。該協議的意圖是一旦迭代器的方法引發,后續調用將繼續這樣的行為。 Python-標準庫 一譯 http://python.usyiyi.cn 廖雪峰 https://www.liaoxuefeng.com/wiki/001374738125095c955...
摘要:判斷奇數是迭代器會根據提供的函數對指定序列做映射語法可以對可迭代對象中的每一個元素進行映射。 python內置庫詳解 1、引言2、內置庫詳解2.1 數據相關2.1...
摘要:從存儲的字符串表示中檢索原始對象的過程稱為。這稱為命名空間。如果需要八進制或十六進制表示,請使用內置函數或。和有什么區別返回對象,而返回列表,并使用相同的內存,無論范圍大小是多少。它提供了靈活性,并允許開發人員為他們的項目使用正確的工具。 ...
摘要:目前有兩種內置集合類型,和。兩個類的構造器具有相同的作用方式返回一個新的或對象,其元素來自于。要表示由集合對象構成的集合,所有的內層集合必須為對象。目前僅有一種標準映射類型字典。 上一篇文章:Python標準庫---14、內置類型:二進制序列類型 (memoryview)下一篇文章:Python標準庫---16、內置類型:上下文管理器類型、其他、特殊屬性 集合類型 --- set, ...
閱讀 1239·2021-11-11 16:55
閱讀 1537·2021-10-08 10:16
閱讀 1188·2021-09-26 10:20
閱讀 3569·2021-09-01 10:47
閱讀 2451·2019-08-30 15:52
閱讀 2682·2019-08-30 13:18
閱讀 3194·2019-08-30 13:15
閱讀 1115·2019-08-30 10:55