摘要:本文為你帶來如何找到長度內置數據類型的使用len() 使用len()與第三方數據類型 提供用于支持len()與用戶定義的類。
本文分享自華為云社區《在 Python 中使用 len() 函數》,作者:Yuchuan 。
在許多情況下,您需要找到存儲在數據結構中的項目數。Python 的內置函數len()是幫助您完成此任務的工具。
在某些情況下, 的使用len()很簡單。但是,有時您需要更詳細地了解此函數的工作原理以及如何將其應用于不同的數據類型。
在本教程中,您將學習如何:
在本文結束時,您將知道何時使用len()Python 函數以及如何有效地使用它。您將知道哪些內置數據類型是有效參數len(),哪些不能使用。您還可以了解如何使用len()第三方類型,如ndarray在與NumPy和DataFrame在大熊貓,并用自己的類。
該函數len()是 Python 的內置函數之一。它返回對象的長度。例如,它可以返回列表中的項目數。您可以將該函數用于許多不同的數據類型。但是,并非所有數據類型都是 的有效參數len()。
您可以從查看此功能的幫助開始:
>>> >>>?help(len) Help?on?built-in?function?len?in?module?builtins: len(obj,?/) ????Return?the?number?of?items?in?a?container.
該函數將一個對象作為參數并返回該對象的長度。該文件對len()去遠一點:
返回對象的長度(項目數)。參數可以是序列(例如字符串、字節、元組、列表或范圍)或集合(例如字典、集合或凍結集合)。(來源)
當您使用內置數據類型和許多帶有 的第三方類型時len(),該函數不需要遍歷數據結構。容器對象的長度存儲為對象的屬性。每次在數據結構中添加或刪除項目時,都會修改此屬性len()的值,并返回長度屬性的值。這確保了len()有效地工作。
在以下部分中,您將了解如何使用len()序列和集合。您還將了解一些不能用作len()Python 函數參數的數據類型。
一個序列是訂購物品的容器。列表、元組和字符串是 Python 中的三個基本內置序列。您可以通過調用找到序列的長度len():
>>> >>>?greeting?=?"Good?Day!" >>>?len(greeting) 9 >>>?office_days?=?["Tuesday",?"Thursday",?"Friday"] >>>?len(office_days) 3 >>>?london_coordinates?=?(51.50722,?-0.1275) >>>?len(london_coordinates) 2
在查找 string greeting、 listoffice_days和 tuple的長度時london_coordinates,您len()以相同的方式使用。所有三種數據類型都是 的有效參數len()。
該函數len()始終返回一個整數,因為它正在計算您傳遞給它的對象中的項目數。0如果參數是空序列,則函數返回:
>>> >>>?len("") 0 >>>?len([]) 0 >>>?len(()) 0
在上面的例子中,你找到了一個空字符串、一個空列表和一個空元組的長度。該函數0在每種情況下都返回。
一個range對象也可以創建使用序列range()。一個range對象不存儲所有的值,但它們產生在需要時他們。但是,您仍然可以range使用len()以下方法找到對象的長度:
>>> >>>?len(range(1,?20,?2)) 10
此數字范圍包括從1到19增量為的整數2。range對象的長度可以通過開始、停止和步長值來確定。
在本節中,您已將len()Python 函數用于字符串、列表、元組和range對象。但是,您也可以將該函數與任何其他內置序列一起使用。
在某些時候,您可能需要在列表或其他序列中查找唯一項的數量。您可以使用集和len()來實現這一點:
>>> >>>?import?random >>>?numbers?=?[random.randint(1,?20)?for?_?in?range(20)] >>>?numbers [3,?8,?19,?1,?17,?14,?6,?19,?14,?7,?6,?1,?17,?10,?8,?14,?17,?10,?2,?5] >>>?unique_numbers?=?set(numbers) {1,?2,?3,?5,?6,?7,?8,?10,?14,?17,?19} >>>?len(unique_numbers) 11
您numbers使用列表推導式生成列表,它包含 20 個介于1和之間的隨機數20。由于您生成的是隨機數,因此每次運行代碼時輸出都會不同。在這個特定的運行中,有 20 個隨機生成的數字列表中有 11 個唯一數字。
您將經常使用的另一種內置數據類型是dictionary。在字典中,每一項都由一個鍵值對組成。當您使用字典作為 的參數時len(),該函數返回字典中的項目數:
>>> >>>?len({"James":?10,?"Mary":?12,?"Robert":?11}) 3 >>>?len({}) 0
第一個示例的輸出顯示此字典中有三個鍵值對。與序列的情況一樣,當參數是空字典或空集時len()將返回0。這導致空字典和空集為假。
您不能使用所有內置數據類型作為len(). 對于其中不存儲多個項目的數據類型,長度的概念不相關。這是數字和布爾類型的情況:
>>> >>>?len(5) Traceback?(most?recent?call?last): ????... TypeError:?object?of?type?'int'?has?no?len() >>>?len(5.5) Traceback?(most?recent?call?last): ?????... TypeError:?object?of?type?'float'?has?no?len() >>>?len(True) Traceback?(most?recent?call?last): ?????... TypeError:?object?of?type?'bool'?has?no?len() >>>?len(5?+?2j) Traceback?(most?recent?call?last): ?????... TypeError:?object?of?type?'complex'?has?no?len()
該整數,浮點數,布爾,以及復雜類型的內置數據類型,你不能使用示例len()。TypeError當參數是沒有長度的數據類型的對象時,該函數會引發 a 。
您還可以探索是否可以使用迭代器和生成器作為參數len():
>>> >>>?import?random >>>?numbers?=?[random.randint(1,?20)?for?_?in?range(20)] >>>?len(numbers) 20 >>>?numbers_iterator?=?iter(numbers) >>>?len(numbers_iterator) Traceback?(most?recent?call?last): ?????... TypeError:?object?of?type?'list_iterator'?has?no?len() >>>?numbers_generator?=?(random.randint(1,?20)?for?_?in?range(20)) >>>?len(numbers_generator) Traceback?(most?recent?call?last): ?????... TypeError:?object?of?type?'generator'?has?no?len()
您已經看到列表具有長度,這意味著您可以將其用作len(). 您可以使用內置函數從列表中創建一個迭代器iter()。在迭代器中,只要需要,就會獲取每個項目,例如在使用函數next()或在循環中時。但是,您不能在len().
你得到了TypeError,當您嘗試使用一個迭代器作為一個參數len()。由于迭代器在需要時獲取每個項目,因此測量其長度的唯一方法是耗盡迭代器。迭代器也可以是無限的,例如由 返回的迭代器itertools.cycle(),因此它的長度無法定義。
不能使用發電機與len()出于同樣的原因。如果不使用它們,就無法測量這些物體的長度。
在本節中,您將了解len(). 這些示例將幫助您更好地了解何時使用此功能以及如何有效地使用它。在某些示例中,您還將看到len()可能的解決方案但可能有更多 Pythonic 方法來實現相同輸出的情況。
的一個常見用例len()是驗證用戶輸入的序列的長度:
#?username.py username?=?input("Choose?a?username:?[4-10?characters]?") if?4?<=?len(username)?<=?10: ????print(f"Thank?you.?The?username?{username}?is?valid") else: ????print("The?username?must?be?between?4?and?10?characters?long")
在此示例中,您使用if語句來檢查 返回的整數len()是否大于或等于4且小于或等于10。你可以運行這個腳本,你會得到一個類似于下面的輸出:
$?python?username.py Choose?a?username:?[4-10?characters]?stephen_g Thank?you.?The?username?stephen_g?is?valid
在這種情況下,用戶名的長度為 9 個字符,因此if語句中的條件計算結果為True。您可以再次運行腳本并輸入無效的用戶名:
$?python?username.py Choose?a?username:?[4-10?characters]?sg The?username?must?be?between?4?and?10?characters?long
在這種情況下,len(username)返回2,并且if語句中的條件計算結果為False。
len()如果您需要檢查可變序列(例如列表)的長度何時達到特定數字,您將使用。在以下示例中,您要求用戶輸入三個用戶名選項,并將它們存儲在列表中:
#?username.py usernames?=?[] print("Enter?three?options?for?your?username") while?len(usernames)?<?3: ????username?=?input("Choose?a?username:?[4-10?characters]?") ????if?4?<=?len(username)?<=?10: ????????print(f"Thank?you.?The?username?{username}?is?valid") ????????usernames.append(username) ????else: ????????print("The?username?must?be?between?4?and?10?characters?long") print(usernames)
您現在使用的從結果len()的while聲明。如果用戶輸入了無效的用戶名,您不會保留輸入。當用戶輸入有效字符串時,您將其附加到列表中usernames。循環重復,直到列表中有三個項目。
您甚至可以len()用來檢查序列何時為空:
>>> >>>?colors?=?["red",?"green",?"blue",?"yellow",?"pink"] >>>?while?len(colors)?>?0: ...?????print(f"The?next?color?is?{colors.pop(0)}") ... The?next?color?is?red The?next?color?is?green The?next?color?is?blue The?next?color?is?yellow The?next?color?is?pink
您使用 list 方法.pop()在每次迭代中從列表中刪除第一項,直到列表為空。如果您在大型列表上使用此方法,則應從列表末尾刪除項目,因為這樣效率更高。您還可以使用內置模塊中的deque數據類型collections,它允許您有效地從左側彈出。
通過使用序列的真實性,有一種更 Pythonic 的方式來實現相同的輸出:
>>> >>>?colors?=?["red",?"green",?"blue",?"yellow",?"pink"] >>>?while?colors: ...????print(f"The?next?color?is?{colors.pop(0)}") ... The?next?color?is?red The?next?color?is?green The?next?color?is?blue The?next?color?is?yellow The?next?color?is?pink
空列表是假的。這意味著該while語句將空列表解釋為False。非空列表是真實的,while語句將其視為True. 返回的值len()決定了序列的真實性。一個序列是truthy當len()返回任何非零整數,并且當falsylen()返回0。
想象一下,您想要生成一個范圍1為的隨機數序列,10并且您希望不斷向該序列添加數字,直到所有數字的總和超過21。以下代碼創建一個空列表并使用while循環填充列表:
>>> >>>?import?random >>>?numbers?=?[] >>>?while?sum(numbers)?<=?21: ...????numbers.append(random.randint(1,?10)) >>>?numbers [3,?10,?4,?7] >>>?numbers[len(numbers)?-?1] 7 >>>?numbers[-1]??#?A?more?Pythonic?way?to?retrieve?the?last?item 7 >>>?numbers.pop(len(numbers)?-?1)??#?You?can?use?numbers.pop(-1) 7 >>>?numbers [3,?10,?4]
您將隨機數附加到列表中,直到總和超過21。當您生成隨機數時,您將獲得的輸出會有所不同。要顯示列表中的最后一個數字,請使用它len(numbers)并1從中減去,因為列表的第一個索引是0。Python 中的索引允許您使用索引-1來獲取列表中的最后一項。因此,雖然您可以len()在這種情況下使用,但您不需要。
您想刪除列表中的最后一個數字,以便列表中所有數字的總和不超過21。您len()再次使用來計算列表中最后一項的索引,您將其用作列表方法的參數.pop()。即使在這種情況下,您也可以將其-1用作.pop()從列表中刪除最后一項并返回它的參數。
如果需要將序列分成兩半,則需要使用表示序列中點的索引。您可以使用len()來查找此值。在以下示例中,您將創建一個隨機數列表,然后將其拆分為兩個較小的列表:
>>> >>>?import?random >>>?numbers?=?[random.randint(1,?10)?for?_?in?range(10)] >>>?numbers [9,?1,?1,?2,?8,?10,?8,?6,?8,?5] >>>?first_half?=?numbers[:?len(numbers)?//?2] >>>?second_half?=?numbers[len(numbers)?//?2?:] >>>?first_half [9,?1,?1,?2,?8] >>>?second_half [10,?8,?6,?8,?5]
在定義 的賦值語句中first_half,使用表示從開頭numbers到中點的項目的切片。您可以通過分解切片表達式中使用的步驟來計算切片表示的內容:
在下一個定義中second_half,在切片中使用相同的表達式。但是,在這種情況下,整數5表示范圍的開始。切片現在5:代表從索引5到列表末尾的項目。
如果您的原始列表包含奇數個項目,則其長度的一半將不再是整數。當您使用整數除法時,您將獲得數字的下限。該列表first_half現在將比 少一項second_half。
您可以通過創建一個包含 11 個數字而不是 10 個數字的初始列表來嘗試這一點。結果列表將不再是一半,但它們將代表最接近拆分奇數序列的替代方法。
您還可以將 Pythonlen()與來自第三方庫的多種自定義數據類型結合使用。在本教程的最后一節中,您將了解 的行為如何len()取決于類定義。在本節中,您將查看使用len()來自兩個流行的第三方庫的數據類型的示例。
該NumPy的模塊是在Python編程的所有定量應用的基石。該模塊介紹了numpy.ndarray數據類型。這種數據類型以及 NumPy 中的函數非常適合數值計算,并且是其他模塊中數據類型的構建塊。
在開始使用 NumPy 之前,您需要安裝該庫。您可以使用 Python 的標準包管理器pip,并在控制臺中運行以下命令:
$?python?-m?pip?install?numpy
您已經安裝了 NumPy,現在您可以從列表中創建一個 NumPy 數組并len()在該數組上使用:
>>> >>>?import?numpy?as?np >>>?numbers?=?np.array([4,?7,?9,?23,?10,?6]) >>>?type(numbers) <class?'numpy.ndarray'> >>>?len(numbers) 6
NumPy 函數從您作為參數傳遞的列表中np.array()創建一個類型的對象numpy.ndarray。
但是,NumPy 數組可以有多個維度。您可以通過將列表列表轉換為數組來創建二維數組:
>>> >>>?import?numpy?as?np >>>?numbers?=?[ ????[11,?1,?10,?10,?15], ????[14,?9,?16,?4,?4], ] >>>?numbers_array?=?np.array(numbers) >>>?numbers_array array([[11,??1,?10,?10,?15], ???????[14,??9,?16,??4,??4]]) >>>?len(numbers_array) 2 >>>?numbers_array.shape (2,?5) >>>?len(numbers_array.shape) 2 >>>?numbers_array.ndim 2
該列表numbers由兩個列表組成,每個列表包含五個整數。當您使用此列表列表創建 NumPy 數組時,結果是一個包含兩行五列的數組。當您將此二維數組作為參數傳遞給 中時,該函數返回數組中的行數len()。
要獲得兩個維度的大小,您可以使用屬性.shape,它是一個顯示行數和列數的元組。您可以通過使用.shape和len()或通過使用 屬性來獲取 NumPy 數組的維數.ndim。
一般來說,當你有一個任意維數的數組時,len()返回第一維的大小:
>>> >>>?import?numpy?as?np >>>?array_3d?=?np.random.randint(1,?20,?[2,?3,?4]) >>>?array_3d array([[[14,??9,?15,?14], ????????[17,?11,?10,??5], ????????[18,??1,??3,?12]], ???????[[?1,??5,??6,?10], ????????[?6,??3,??1,?12], ????????[?1,??4,??4,?17]]]) >>>?array_3d.shape (2,?3,?4) >>>?len(array_3d) 2
在本例中,您將創建一個三維數組,其形狀為(2, 3, 4)其中每個元素都是1和之間的隨機整數20。這次您使用該函數np.random.randint()創建了一個數組。函數len()返回2,這是第一個維度的大小。
查看NumPy 教程:您在 Python 中進入數據科學的第一步,了解有關使用 NumPy 數組的更多信息。
pandas庫中的DataFrame類型是另一種在許多應用程序中廣泛使用的數據類型。
在使用 pandas 之前,您需要在控制臺中使用以下命令進行安裝:
$?python?-m?pip?install?pandas
您已經安裝了 pandas 包,現在您可以從字典創建一個 DataFrame:
>>> >>>?import?pandas?as?pd >>>?marks?=?{ ????"Robert":?[60,?75,?90], ????"Mary":?[78,?55,?87], ????"Kate":?[47,?96,?85], ????"John":?[68,?88,?69], } >>>?marks_df?=?pd.DataFrame(marks,?index=["Physics",?"Math",?"English"]) >>>?marks_df ?????????Robert??Mary??Kate??John Physics??????60????78????47????68 Math?????????75????55????96????88 English??????90????87????85????69 >>>?len(marks_df) 3 >>>?marks_df.shape (3,?4)
字典的鍵是代表班級學生姓名的字符串。每個鍵的值是一個列表,其中包含三個主題的標記。當您從此字典創建 DataFrame 時,您可以使用包含主題名稱的列表來定義索引。
DataFrame 有三行四列。該函數len()返回 DataFrame 中的行數。該DataFrame類型還有一個.shape屬性,您可以使用它來顯示 DataFrame 的第一個維度表示行數。
您已經了解了如何len()使用許多內置數據類型以及來自第三方模塊的一些數據類型。在下一節中,您將學習如何定義任何類,以便將其用作len()Python 函數的參數。
您可以在The Pandas DataFrame: Make Working With Data Delightful 中進一步探索 pandas 模塊。
當您定義一個類時,您可以定義的特殊方法之一是.__len__(). 這些特殊方法被稱為 dunder 方法,因為它們在方法名稱的開頭和結尾都有雙下劃線。Python 的內置len()函數調用其參數的.__len__()方法。
在上一節中,您已經看到了len()當參數是一個 pandasDataFrame對象時的行為。此行為由類的.__len__()方法決定DataFrame,您可以在以下模塊的源代碼中看到pandas.core.frame:
class?DataFrame(NDFrame,?OpsMixin): ????#?... ????def?__len__(self)?->?int: ????????""" ????????Returns?length?of?info?axis,?but?here?we?use?the?index. ????????""" ????????return?len(self.index)
此方法使用 返回 DataFrame.index屬性的長度len()。此 dunder 方法將 DataFrame 的長度定義為等于 DataFrame 中的行數,如 所示.index。
您可以.__len__()通過以下玩具示例進一步探索dunder 方法。您將定義一個名為YString. 此數據類型基于內置字符串類,但類型對象YString賦予字母 Y 比所有其他字母更重要:
#?ystring.py class?YString(str): ????def?__init__(self,?text): ????????super().__init__() ????def?__str__(self): ????????"""Display?string?as?lowercase?except?for?Ys?that?are?uppercase""" ????????return?self.lower().replace("y",?"Y") ????def?__len__(self): ????????"""Returns?the?number?of?Ys?in?the?string""" ????????return?self.lower().count("y")
.__init__()方法YString使用.__init__()父str類的方法初始化對象。您可以使用函數來實現這一點super()。該.__str__()方法定義了對象的顯示方式。函數str()、print()和format()都調用此方法。對于此類,您將對象表示為全小寫字符串,但字母 Y 除外,它顯示為大寫。
對于這個玩具類,您將對象的長度定義為字符串中字母 Y 的出現次數。因此,該.__len__()方法返回字母 Y 的計數。
您可以創建一個類的對象YString并找到它的長度。用于上述示例的模塊名稱是ystring.py:
>>> >>>?from?ystring?import?YString >>>?message?=?YString("Real?Python??Yes!?Start?reading?today?to?learn?Python") >>>?print(message) real?pYthon??Yes!?start?reading?todaY?to?learn?pYthon >>>?len(message)??#?Returns?number?of?Ys?in?message 4
您YString從類型對象創建類型對象str并使用 顯示對象的表示print()。然后將該對象message用作 的參數len()。這將調用類的.__len__()方法,結果是字母 Y 在 中的出現次數message。在這種情況下,字母 Y 出現了四次。
YString該類不是一個非常有用的類,但它有助于說明如何自定義 的行為len()以滿足您的需要。該.__len__()方法必須返回一個非負整數。否則,它會引發錯誤。
另一個特殊的方法是.__bool__()方法,它決定了如何將對象轉換為布爾值。該.__bool__()dunder方法通常不用于序列和集合定義。在這些情況下,該.__len__()方法確定對象的真實性:
>>> >>>?from?ystring?import?YString >>>?first_test?=?"tomorrow" >>>?second_test?=?"today" >>>?bool(first_test) True >>>?bool(YString(first_test)) False >>>?bool(second_test) True >>>?bool(YString(second_test)) True
變量first_string中沒有 Y。如 的輸出所示bool(),該字符串為真,因為它非空。但是,當您YString從此字符串創建類型的對象時,新對象是假的,因為字符串中沒有 Y 字母。因此,len()返回0。相反,變量second_string確實包含字母 Y,因此字符串和類型的對象YString都是真值。
您可以在 Python 3 中的面向對象編程 (OOP) 中閱讀有關使用面向對象編程和定義類的更多信息。
您已經探索了如何使用len()來確定序列、集合和其他同時包含多個項目的數據類型(例如 NumPy 數組和 Pandas DataFrames)中的項目數量。
該len()Python函數是在許多程序中的關鍵工具。它的一些用途很簡單,但正如您在本教程中看到的那樣,此功能比最基本的用例要多得多。了解何時可以使用此功能以及如何有效地使用它將有助于您編寫更整潔的代碼。
在本教程中,您學習了如何:
您現在已為理解該len()函數奠定了良好的基礎。len()了解更多 about可以幫助您更好地理解數據類型之間的差異。您已準備好在len()您的算法中使用,并通過使用.__len__()方法增強某些類定義來改進它們的功能。
?
|