摘要:本文為你帶來如何找到長度內置數據類型的使用len() 使用len()與第三方數據類型 提供用於支持len()與用戶定義的類。
本文分享自華為雲社區《在 Python 中使用 len() 函數》,作者:Yuchuan 。
在許多情況下,您需要找到存儲在數據結構中的項目數。Python 的內置函數len()是幫助您完成此任務的工具。
在某些情況下, 的使用len()很簡單。但是,有時您需要更詳細地了解此函數的工作原理以及如何將其應用於不同的數據類型。
在本教程中,您將學習如何:
- 找到的長度內置數據類型的使用len()
- 使用len()與第三方數據類型
- 提供用於支持len()與用戶定義的類
在本文結束時,您將知道何時使用len()Python 函數以及如何有效地使用它。您將知道哪些內置數據類型是有效參數len(),哪些不能使用。您還可以了解如何使用len()第三方類型,如ndarray在與NumPy和DataFrame在大熊貓,並用自己的類。
Python 入門 len()
該函數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 函數參數的數據類型。
使用len()內置序列
一個序列是訂購物品的容器。列表、元組和字符串是 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("") 0 >>> len([]) 0 >>> len(()) 0
此數字范圍包括從1到19增量為的整數2。range對象的長度可以通過開始、停止和步長值來確定。
在本節中,您已將len()Python 函數用於字符串、列表、元組和range對象。但是,您也可以將該函數與任何其他內置序列一起使用。
使用len()帶內置集合
在某些時候,您可能需要在列表或其他序列中查找唯一項的數量。您可以使用集和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(). 對於其中不存儲多個項目的數據類型,長度的概念不相關。這是數字和布爾類型的情況:
>>> >>> 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(). 這些示例將幫助您更好地了解何時使用此功能以及如何有效地使用它。在某些示例中,您還將看到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到中點的項目的切片。您可以通過分解切片表達式中使用的步驟來計算切片表示的內容:
- 首先,len(numbers)返回整數10。
- 接下來,10 // 2在5使用整數除法運算符時返回整數。
- 最后,0:5是一個切片,表示前五個項目,其索引0為4。請注意,端點被排除在外。
在下一個定義中second_half,在切片中使用相同的表達式。但是,在這種情況下,整數5表示范圍的開始。切片現在5:代表從索引5到列表末尾的項目。
如果您的原始列表包含奇數個項目,則其長度的一半將不再是整數。當您使用整數除法時,您將獲得數字的下限。該列表first_half現在將比 少一項second_half。
您可以通過創建一個包含 11 個數字而不是 10 個數字的初始列表來嘗試這一點。結果列表將不再是一半,但它們將代表最接近拆分奇數序列的替代方法。
將len()函數與第三方庫一起使用
您還可以將 Pythonlen()與來自第三方庫的多種自定義數據類型結合使用。在本教程的最后一節中,您將了解 的行為如何len()取決於類定義。在本節中,您將查看使用len()來自兩個流行的第三方庫的數據類型的示例。
NumPy 的 ndarray
該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庫中的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()用戶定義的類
當您定義一個類時,您可以定義的特殊方法之一是.__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()與第三方數據類型
- 提供用於支持len()與用戶定義的類
您現在已為理解該len()函數奠定了良好的基礎。len()了解更多 about可以幫助您更好地理解數據類型之間的差異。您已准備好在len()您的算法中使用,並通過使用.__len__()方法增強某些類定義來改進它們的功能。