写点什么

从零到熟悉,带你掌握 Python len() 函数的使用

发布于: 刚刚

摘要:本文为你带来如何找到长度内置数据类型的使用 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(range(1, 20, 2))10
复制代码

此数字范围包括从 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.pyChoose a username: [4-10 characters] stephen_gThank you. The username stephen_g is valid
复制代码


在这种情况下,用户名的长度为 9 个字符,因此 if 语句中的条件计算结果为 True。您可以再次运行脚本并输入无效的用户名:


$ python username.pyChoose a username: [4-10 characters] sgThe 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 redThe next color is greenThe next color is blueThe next color is yellowThe 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 redThe next color is greenThe next color is blueThe next color is yellowThe 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 item7
>>> 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 到中点的项目的切片。您可以通过分解切片表达式中使用的步骤来计算切片表示的内容:

  1. 首先,len(numbers)返回整数 10。

  2. 接下来,10 // 2 在 5 使用整数除法运算符时返回整数。

  3. 最后,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_arrayarray([[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.ndim2
复制代码


该列表 numbers 由两个列表组成,每个列表包含五个整数。当您使用此列表列表创建 NumPy 数组时,结果是一个包含两行五列的数组。当您将此二维数组作为参数传递给 中时,该函数返回数组中的行数 len()。


要获得两个维度的大小,您可以使用属性.shape,它是一个显示行数和列数的元组。您可以通过使用.shape 和 len()或通过使用 属性来获取 NumPy 数组的维数.ndim。


一般来说,当你有一个任意维数的数组时,len()返回第一维的大小:


>>>>>> import numpy as np
>>> array_3d = np.random.randint(1, 20, [2, 3, 4])>>> array_3darray([[[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 JohnPhysics 60 78 47 68Math 75 55 96 88English 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 message4
复制代码


您 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__()方法增强某些类定义来改进它们的功能。


点击关注,第一时间了解华为云新鲜技术~

发布于: 刚刚阅读数: 2
用户头像

提供全面深入的云计算技术干货 2020.07.14 加入

华为云开发者社区,提供全面深入的云计算前景分析、丰富的技术干货、程序样例,分享华为云前沿资讯动态,方便开发者快速成长与发展,欢迎提问、互动,多方位了解云计算! 传送门:https://bbs.huaweicloud.com/

评论

发布
暂无评论
从零到熟悉,带你掌握Python len() 函数的使用