Python len() 函数

Python len() 语法

len() 是 Python 的一个内置函数,它用于获取一个对象的长度(即元素个数),该对象可以是以下类型:

  • 序列类型:列表、元组、字符串、bytes、bytearray、range 对象等。
  • 映射类型:字典、集合、frozenset 等。
  • 自定义对象:实现了 __len__() 方法的任意对象。

语法:

len(object)

说明:

len() 函数接收单个参数。

  • object(必选):可以是上面提到的任意一种类型。

注意:

  • 如果尝试对一个没有定义 __len__() 方法的对象(例如一个普通的整数或浮点数)使用 len(),将会引发 TypeError 异常。
  • len() 函数的时间复杂度通常是 O(1),因为它通常直接返回对象存储的预计算长度,而不是遍历所有元素。这使得它在处理大型数据结构时效率极高。

Python len() 摘要

使用频率
时间复杂度 O(1)
官方文档 查看
相关函数 range()enumerate()sum()

Python len() 示例

接下来,我们通过几个简单的例子来讲解一下 Python len() 函数是如何使用的。

示例 1:len() 用于序列类型(列表、元组、字符串)

# 列表
a = ['红', '绿', '蓝']
print(len(a))

# 元组
b = ('红', '绿', '蓝')
print(len(b))

# 字符串
c = '绿叶网'
print(len(c))

运行结果如下。

3
3
3

示例 2:len() 用于映射类型(字典、集合)

# 字典
a = {'Jack': 1001, 'Lucy': 1002}
print(len(a))

# 集合
b = {'red', 'green', 'blue'}
print(len(b))

运行结果如下。

2
3

示例 3:len() 用于 range 对象

result = range(1, 10)
print(len(result))

运行结果如下。

9

示例 4:len() 用于 frozenset

result = frozenset(range(5))
print(len(result))

运行结果如下。

5

分析:

如果小伙伴们不了解 frozenset 类型,请先阅读:Python frozenset() 函数

示例 5:len() 用于 bytes 和 bytearray

b1 = bytes('lvyenet', 'utf-8')
b2 = bytearray('lvyenet', 'utf-8')

print(len(b1))
print(len(b2))

运行结果如下。

7
7

分析:

如果小伙伴们对 bytes 和 bytearray 这 2 种类型并不熟悉,请先阅读以下 2 篇文章。

Python bytes() 函数

Python bytearray() 函数

深入了解 len()

只有实现了 __len__() 方法的对象,才能使用 len() 函数计算长度。如果一个对象没有实现 __len__() 方法,那么调用 len() 函数会抛出 TypeError 异常。

示例 6:对象实现了 __len__() 方法

class Session:
    def __init__(self, number = 0):
        self.number = number
    
    def __len__(self):
        return self.number

s1 = Session()
print(len(s1))

s2 = Session(6)
print(len(s2))

运行结果如下。

0
6

示例 7:对象没有实现 __len__() 方法

class Session:
    pass

s = Session()
print(len(s))

运行结果如下。

(报错) TypeError: object of type 'Session' has no len()

len() 性能建议

虽然 len() 函数本身效率很高(通常是 O(1)),但在某些特定场景下,不恰当的使用方式仍然可能影响程序性能。了解以下这些建议,可以帮助我们写出更高效的 Python 代码。

1. 避免重复调用 len()

对于可变对象(如列表),重复调用 len() 可能会导致不必要的性能开销,尤其是在循环中。因为我们更加推荐先将长度值存储到一个变量中,然后在循环中使用该变量。

比如,length = len(lst) 比在每次迭代中调用 len(lst) 更高效,因为前者只需计算一次长度,而后者会重复计算多次。

# 不推荐(每次循环都会重新计算 len)
i = 0
while i < len(lst):
    print(lst[i])
    i += 1

# 推荐(只计算一次)
length = len(lst)
i = 0
while i < length:
    print(lst[i])
    i += 1

需要注意的是,对于 for i in range(len(lst)): 这种写法,len(lst) 只会在循环开始前被计算一次,因此不存在重复计算的性能问题。

2. 生成器表达式

生成器表达式是惰性计算的,不会立即生成所有值,因此无法直接使用 len() 函数计算其长度。如果需要计算生成器的长度,可以先将其转换为列表,然后再调用 len() 函数。

比如在下面代码中,len(list(gen)) 会将生成器 gen 的所有值加载到列表中,然后计算其长度,但要注意这会消耗生成器的所有元素。

gen = (x for x in range(5))
print(len(list(gen)))      # 输出 5

常见问题

1. 为什么 len(True) 会报错?

因为布尔类型不是容器,它本身是不实现 __len__() 方法的。我们需要先将其转换为 int 类型或使用其他类型。

2. 如何计算多维列表的元素总数?

我们可以递归计算或迭代计算,比如:

def total_len(obj):
    if isinstance(obj, (list, tuple, set)):
        return sum(total_len(item) for item in obj)
    else:
        return 1

nested_list = [[1, 2], [3, [4, 5]]]
print(total_len(nested_list))      # 输出:5

上一篇: range()

下一篇: slice()

给站长反馈

绿叶网正在不断完善中,小伙伴们如果发现任何问题,还望多多给站长反馈,谢谢!

邮箱:lvyenet@vip.qq.com

「绿叶网」服务号
绿叶网服务号放大
关注服务号,微信也能看教程。
绿叶网服务号