pin_drop当前位置:知识文库 ❯ 图文

Python len()函数 字符串列表字典长度获取

一、函数概述

Python内置函数len()用于获取对象的长度或元素个数,是Python中最常用的内置函数之一。它支持所有内置容器类型(字符串、列表、元组、字典、集合等),并可通过实现__len__魔术方法扩展到自定义类。

  • 通用性:支持所有内置容器类型

  • O(1)复杂度:内置容器获取长度是常数时间

  • 可扩展:自定义类实现__len__即可使用len()

  • 条件判断:空容器len()为0,在布尔上下文中为False


二、语法详解

属性 说明
语法 len(s)
参数 s:序列(如字符串、列表、元组)或集合
返回值 整数,对象的元素个数
返回值类型 int(非负整数)
底层调用 s.__len__()
数据类型 len()的含义 示例 结果
字符串 str 字符个数 len("hello") 5
列表 list 元素个数 len([1, 2, 3]) 3
元组 tuple 元素个数 len((1, 2)) 2
字典 dict 键值对个数 len({"a": 1}) 1
集合 set 唯一元素个数 len({1, 2, 3}) 3
字节 bytes 字节数 len(b"abc") 3

三、len()基础用法

示例1:字符串长度

代码示例

# 基本字符串
text1 = "hello"
print(f"'hello' 的长度: {len(text1)}")

# 空字符串
text2 = ""
print(f"空字符串长度: {len(text2)}")

# 包含空格和标点
text3 = "hello world!"
print(f"'hello world!' 的长度: {len(text3)}")

# 中文字符(每个中文字符算1个)
text4 = "你好世界"
print(f"'你好世界' 的长度: {len(text4)}")

# 转义字符(\n、\t各算1个字符)
text5 = "a\nb\tc"
print(f"'a\\nb\\tc' 的长度: {len(text5)}")

输出结果:

代码示例

'hello' 的长度: 5
空字符串长度: 0
'hello world!' 的长度: 12
'你好世界' 的长度: 4
'a\nb\tc' 的长度: 5

示例2:列表与元组长度

代码示例

# 列表
empty_list = []
numbers = [1, 2, 3, 4, 5]
mixed = [1, "hello", 3.14, True]
nested = [[1, 2], [3, 4], [5, 6]]

print(f"空列表长度: {len(empty_list)}")
print(f"numbers长度: {len(numbers)}")
print(f"mixed长度: {len(mixed)}")
print(f"nested长度: {len(nested)}")  # 注意:只计算外层元素

# 元组
empty_tuple = ()
point = (3, 4)
colors = ("红", "绿", "蓝")

print(f"\n空元组长度: {len(empty_tuple)}")
print(f"point长度: {len(point)}")
print(f"colors长度: {len(colors)}")

# 单元素元组(注意逗号)
single = (42,)
print(f"single长度: {len(single)}")

输出结果:

代码示例

空列表长度: 0
numbers长度: 5
mixed长度: 4
nested长度: 3

空元组长度: 0
point长度: 2
colors长度: 3
single长度: 1

示例3:字典与集合长度

代码示例

# 字典(键值对数量)
empty_dict = {}
student = {"name": "张三", "age": 20, "grade": "A"}
nested_dict = {"a": {"b": 1}, "c": {"d": 2}}

print(f"空字典长度: {len(empty_dict)}")
print(f"student长度: {len(student)}")
print(f"nested_dict长度: {len(nested_dict)}")  # 只计算顶层键

# 集合(去重后的元素数量)
empty_set = set()
unique_nums = {1, 2, 3, 3, 2, 1}
fruits = {"苹果", "香蕉", "橘子"}

print(f"\n空集合长度: {len(empty_set)}")
print(f"unique_nums长度: {len(unique_nums)}")  # 去重后
print(f"fruits长度: {len(fruits)}")

输出结果:

代码示例

空字典长度: 0
student长度: 3
nested_dict长度: 2

空集合长度: 0
unique_nums长度: 3
fruits长度: 3

四、各类数据结构的len()

示例1:range与bytes

代码示例

# range对象
r1 = range(10)
r2 = range(2, 10)
r3 = range(0, 20, 3)

print(f"range(10) 长度: {len(r1)}")
print(f"range(2, 10) 长度: {len(r2)}")
print(f"range(0, 20, 3) 长度: {len(r3)}")

# bytes对象
b1 = b"hello"
b2 = bytes([65, 66, 67])
b3 = b""

print(f"\nb'hello' 长度: {len(b1)}")
print(f"bytes([65,66,67]) 长度: {len(b2)}")
print(f"空bytes长度: {len(b3)}")

# bytearray(可变的字节序列)
ba = bytearray(b"abc")
print(f"bytearray长度: {len(ba)}")

输出结果:

代码示例

range(10) 长度: 10
range(2, 10) 长度: 8
range(0, 20, 3) 长度: 7

b'hello' 长度: 5
bytes([65,66,67]) 长度: 3
空bytes长度: 0
bytearray长度: 3

示例2:嵌套结构的长度

代码示例

# 注意:len()只计算最外层元素个数
matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]
print(f"矩阵外层长度: {len(matrix)}")
print(f"第一行长度: {len(matrix[0])}")

# 计算总元素数(需要遍历)
total = sum(len(row) for row in matrix)
print(f"矩阵总元素数: {total}")

# 嵌套字典
data = {
    "users": [
        {"name": "张三", "age": 25},
        {"name": "李四", "age": 30}
    ],
    "count": 2
}
print(f"\ndata顶层键数量: {len(data)}")
print(f"users列表长度: {len(data['users'])}")

输出结果:

代码示例

矩阵外层长度: 3
第一行长度: 3
矩阵总元素数: 9

data顶层键数量: 2
users列表长度: 2

五、__len__魔术方法

示例1:实现自定义容器的len()

代码示例

class ShoppingCart:
    def __init__(self):
        self.items = []
    
    def add(self, name, price):
        self.items.append({"name": name, "price": price})
    
    def __len__(self):
        return len(self.items)
    
    def __bool__(self):
        return len(self.items) > 0

cart = ShoppingCart()
print(f"空购物车长度: {len(cart)}")
print(f"空购物车布尔值: {bool(cart)}")

cart.add("笔记本电脑", 5999)
cart.add("鼠标", 99)
cart.add("键盘", 199)

print(f"\n添加商品后长度: {len(cart)}")
print(f"购物车布尔值: {bool(cart)}")

输出结果:

代码示例

空购物车长度: 0
空购物车布尔值: False

添加商品后长度: 3
购物车布尔值: True

示例2:动态计算长度

代码示例

class EvenNumbers:
    """只存储偶数的集合"""
    def __init__(self, limit):
        self.limit = limit
    
    def __len__(self):
        # 动态计算,不实际存储
        return self.limit // 2
    
    def __contains__(self, n):
        return n % 2 == 0 and 0 <= n < self.limit

evens = EvenNumbers(20)
print(f"0-19中偶数个数: {len(evens)}")  # 10个:0,2,4,6,8,10,12,14,16,18

evens100 = EvenNumbers(100)
print(f"0-99中偶数个数: {len(evens100)}")  # 50个

输出结果:

代码示例

0-19中偶数个数: 10
0-99中偶数个数: 50

示例3:组合多个容器的长度

代码示例

class MultiContainer:
    def __init__(self):
        self.lists = []
    
    def add_list(self, lst):
        self.lists.append(lst)
    
    def __len__(self):
        # 返回所有列表元素的总数
        return sum(len(lst) for lst in self.lists)
    
    def container_count(self):
        return len(self.lists)

mc = MultiContainer()
mc.add_list([1, 2, 3])
mc.add_list([4, 5])
mc.add_list([6, 7, 8, 9])

print(f"容器数量: {mc.container_count()}")
print(f"总元素数: {len(mc)}")  # 3 + 2 + 4 = 9

输出结果:

代码示例

容器数量: 3
总元素数: 9

六、len()的高级应用

示例1:条件判断与边界检查

代码示例

def process_data(data, max_size=100):
    """处理数据,带有长度检查"""
    length = len(data)
    
    if length == 0:
        print("错误: 数据为空")
        return None
    
    if length > max_size:
        print(f"警告: 数据长度{length}超过最大值{max_size}")
        data = data[:max_size]
    
    print(f"处理{len(data)}个元素...")
    return data

# 测试
print("--- 空数据 ---")
process_data([])

print("\n--- 正常数据 ---")
process_data([1, 2, 3, 4, 5])

print("\n--- 超大数 ---")
process_data(list(range(200)))

输出结果:

代码示例

--- 空数据 ---
错误: 数据为空

--- 正常数据 ---
处理5个元素...

--- 超大数 ---
警告: 数据长度200超过最大值100
处理100个元素...

示例2:len()在循环中的使用

代码示例

# 传统索引遍历
fruits = ["苹果", "香蕉", "橘子", "葡萄"]

print("--- 使用len()控制循环 ---")
for i in range(len(fruits)):
    print(f"{i}: {fruits[i]}")

# 更Pythonic的方式(推荐)
print("\n--- enumerate方式(推荐)---")
for i, fruit in enumerate(fruits):
    print(f"{i}: {fruit}")

# 反向遍历
print("\n--- 反向遍历 ---")
for i in range(len(fruits) - 1, -1, -1):
    print(f"{i}: {fruits[i]}")

# 最佳反向遍历方式
print("\n--- reversed方式(推荐)---")
for i, fruit in enumerate(reversed(fruits)):
    print(f"倒数{i+1}: {fruit}")

输出结果:

代码示例

--- 使用len()控制循环 ---
0: 苹果
1: 香蕉
2: 橘子
3: 葡萄

--- enumerate方式(推荐)---
0: 苹果
1: 香蕉
2: 橘子
3: 葡萄

--- 反向遍历 ---
3: 葡萄
2: 橘子
1: 香蕉
0: 苹果

--- reversed方式(推荐)---
倒数1: 葡萄
倒数2: 橘子
倒数3: 香蕉
倒数4: 苹果

示例3:统计文件行数

代码示例

# 模拟文件内容
file_content = """第一行:Python教程
第二行:len()函数详解
第三行:示例代码
第四行:总结
""".strip().split("\n")

# 方法1:直接len()
print(f"文件行数: {len(file_content)}")

# 方法2:统计非空行
non_empty = sum(1 for line in file_content if line.strip())
print(f"非空行数: {non_empty}")

# 方法3:包含特定关键词的行
keyword_lines = sum(1 for line in file_content if "len" in line)
print(f"包含'len'的行数: {keyword_lines}")

输出结果:

代码示例

文件行数: 4
非空行数: 4
包含'len'的行数: 1

七、注意事项

注意1:len()不支持迭代器和生成器:迭代器和生成器没有固定的长度,因为它们可以产生无限元素或延迟计算。对它们使用len()会抛出TypeError。如需计算迭代器元素个数,需先转换为列表:len(list(iterator))(会消耗迭代器)。

注意2:len()返回非负整数__len__方法必须返回非负整数。如果返回负数,len()会抛出ValueError。如果返回非整数类型,会抛出TypeError。

注意3:中文字符与字节长度:len()对字符串返回的是Unicode字符数,不是字节数。中文字符每个算1个。如果需要字节长度,需先编码:len("中文".encode("utf-8"))返回6(UTF-8下每个中文3字节)。

注意4:__len__应为O(1)操作:根据Python规范,__len__方法应该是一个快速操作(最好O(1))。如果需要复杂计算才能确定长度,建议提供其他方法名(如count()、size())而不是实现__len__,以免误导使用者认为len()很快。

注意5:嵌套结构只计算顶层:len()只计算容器最外层的元素个数,不会递归计算嵌套结构中的元素。如len([[1,2],[3,4]])返回2,不是4。需要递归计算时应自行实现。


小贴士

len()与布尔值的隐式转换:在Python中,如果一个类实现了__len__方法但没有实现__bool__,则bool(obj)会根据len(obj) != 0来判断。这意味着空容器在条件判断中自动为False,非空为True,非常便于编写if data:这样的简洁代码。

八、练习题

练习1

编写一个RecursiveLength类,提供递归计算嵌套结构长度的功能:
(1)total_length(obj):递归计算嵌套列表/元组中所有基本元素的总数
(2)depth(obj):计算嵌套的最大深度
(3)max_width(obj):计算任意层级的最大宽度
(4)测试:[1, [2, 3], [[4, 5], 6]] 的总长度、深度和最大宽度

练习2

编写一个FixedSizeQueue类,实现固定长度的队列:
(1)初始化时接收maxlen参数
(2)实现__len__返回当前元素个数
(3)实现push(item):添加元素,超出maxlen时移除最旧元素
(4)实现__bool__:队列非空返回True
(5)测试:创建maxlen=3的队列,添加5个元素,观察长度变化


常见问题

len()的时间复杂度是多少?

对于Python内置容器(list、str、dict、set等),len()的时间复杂度是O(1),因为它们在内部维护了长度信息。但对于自定义类,取决于__len__的实现。如果__len__需要遍历计算,则可能是O(n)。

为什么生成器和迭代器不能使用len()?

生成器和迭代器是惰性求值的,元素在被需要时才产生。它们可能产生无限序列,也可能在运行时才能确定有多少元素。因此没有固定的长度概念。如果需要知道元素个数,必须消费整个迭代器:sum(1 for _ in generator)

len()可以返回负数吗?

不可以。Python规定__len__必须返回非负整数。如果返回负数,len()会抛出ValueError: __len__() should return >= 0。这是为了保证len()的语义一致性,长度不可能是负数。

如何判断对象是否支持len()?

可以使用hasattr检查:hasattr(obj, '__len__')。更规范的方式是使用collections.abc.Sized:isinstance(obj, collections.abc.Sized)。Sized抽象基类标记了所有支持len()的类型。

标签: len函数 __len__ 对象长度 Python内置函数 魔术方法 容器类型 元素个数

本文涉及AI创作

内容由AI创作,请仔细甄别

list快速访问

上一篇: Python iter next函数 - 迭代器与StopIteration机制 下一篇: Python max和min函数 - 求最大值最小值

poll相关推荐