当前位置: 首页 > news >正文

python中的容器与自定义容器

        在Python中,容器(Container)是用于存储和组织其他对象的对象。Python提供了多种内置容器类型,同时也允许开发者创建自定义容器类型。

一、内置容器

1.常见的内置容器

(1). 列表 (list)

  • 可变序列,有序集合

  • 支持索引、切片、修改

my_list = [1, "hello", 3.14]
my_list[0] = 100  # 修改元素

(2). 元组 (tuple)

  • 不可变序列,有序集合

  • 创建后无法修改元素

my_tuple = (1, "world", 2.71)
# my_tuple[0] = 100  # 错误!不可修改

(3). 字典 (dict)

  • 键值对映射,无序集合

  • 键必须是不可变类型(如字符串、数字、元组)

my_dict = {"name": "Alice", "age": 30}
print(my_dict["name"])  # 输出: Alice

(4). 集合 (set)

  • 无序不重复元素集

  • 支持数学集合运算(并集、交集等)

my_set = {1, 2, 3, 2}  # 自动去重: {1, 2, 3}

(5).字符串(String)

字符序列(虽然主要用于文本处理,但也是容器)

2.内置容器的常见操作

(1). 通用容器操作

所有容器类型都支持以下操作:

# 成员测试
x in container  # 判断元素是否存在
x not in container  # 判断元素是否不存在# 长度
len(container)  # 获取容器中元素数量# 迭代
for item in container:  # 遍历容器元素print(item)

(2). 序列类型(List, Tuple, String)特有操作 

# 索引访问
container[index]  # 获取指定位置的元素# 切片
container[start:stop:step]  # 获取子序列# 连接
container1 + container2  # 序列连接# 重复
container * n  # 序列重复n次

3. 可变序列(List)特有操作 

# 修改元素
container[index] = value  # 修改指定位置的元素# 切片赋值
container[start:stop] = [values]  # 修改子序列# 添加元素
container.append(item)  # 末尾添加
container.extend(iterable)  # 扩展多个元素
container.insert(index, item)  # 指定位置插入# 删除元素
del container[index]  # 删除指定位置元素
container.remove(item)  # 删除第一个匹配项
container.pop([index])  # 删除并返回指定位置元素(默认最后一个)# 排序和反转
container.sort()  # 原地排序
container.reverse()  # 原地反转

二、自定义容器

        在 Python 里,除了使用列表、元组、字典等内置容器外,还能通过自定义类的方式创建符合特定需求的容器。

1. 基本概念        

        自定义容器意味着创建一个类,让这个类的实例能像内置容器(如列表、字典)一样进行操作,例如添加元素、删除元素、迭代等。为了实现这些功能,需要在类中实现一些特殊方法(也称为魔术方法)。

2.实现自定义容器所需的特殊方法

(1).__init__ 方法

这是类的构造函数,用于初始化容器的状态。

class MyContainer:def __init__(self):self.items = []

(2).__len__ 方法

该方法用于返回容器中元素的数量,当使用 len() 函数作用于容器实例时会调用此方法。

class MyContainer:def __init__(self):self.items = []def __len__(self):return len(self.items)container = MyContainer()
print(len(container))  # 输出: 0

(3).__getitem__ 方法

通过该方法可以使用索引来访问容器中的元素,就像使用 [] 操作符一样。

class MyContainer:def __init__(self):self.items = []def __getitem__(self, index):return self.items[index]def add_item(self, item):self.items.append(item)container = MyContainer()
container.add_item(10)
container.add_item(20)
print(container[0])  # 输出: 10

(4).__setitem__ 方法

此方法用于通过索引来设置容器中元素的值。

class MyContainer:def __init__(self):self.items = []def __getitem__(self, index):return self.items[index]def __setitem__(self, index, value):self.items[index] = valuedef add_item(self, item):self.items.append(item)container = MyContainer()
container.add_item(10)
container[0] = 20
print(container[0])  # 输出: 20

(5).__delitem__ 方法

用于通过索引删除容器中的元素。

class MyContainer:def __init__(self):self.items = []def __getitem__(self, index):return self.items[index]def __setitem__(self, index, value):self.items[index] = valuedef __delitem__(self, index):del self.items[index]def add_item(self, item):self.items.append(item)container = MyContainer()
container.add_item(10)
del container[0]
print(len(container))  # 输出: 0

(6). __contains__ 方法

当使用 in 操作符检查元素是否在容器中时,会调用此方法。

class MyContainer:def __init__(self):self.items = []def __contains__(self, item):return item in self.itemsdef add_item(self, item):self.items.append(item)container = MyContainer()
container.add_item(10)
print(10 in container)  # 输出: True

 (7).__iter__ 和 __next__ 方法(迭代器协议)

  • __iter__ 方法返回一个迭代器对象,通常就是容器对象本身。
  • __next__ 方法用于返回迭代器的下一个元素,当没有更多元素时,需要抛出 StopIteration 异常。
class MyContainer:def __init__(self):self.items = []self.index = 0def __iter__(self):return selfdef __next__(self):if self.index < len(self.items):result = self.items[self.index]self.index += 1return resultelse:self.index = 0raise StopIterationdef add_item(self, item):self.items.append(item)container = MyContainer()
container.add_item(10)
container.add_item(20)
for item in container:print(item)  # 依次输出: 10, 20

3.示例

 示例一:自定义字典容器

class MyDictContainer:def __init__(self):self.data = {}def __getitem__(self, key):return self.data.get(key)def __setitem__(self, key, value):self.data[key] = valuedef __delitem__(self, key):if key in self.data:del self.data[key]def __contains__(self, key):return key in self.datadef __len__(self):return len(self.data)def __iter__(self):return iter(self.data)my_dict = MyDictContainer()
my_dict['name'] = 'Alice'
my_dict['age'] = 25
print(my_dict['name'])  # 输出: Alice
print('age' in my_dict)  # 输出: True
del my_dict['age']
print(len(my_dict))  # 输出: 1
for key in my_dict:print(key)  # 输出: name

示例二:自定义序列类

class MySequence:def __init__(self, items):self._items = list(items)def __len__(self):return len(self._items)def __getitem__(self, index):return self._items[index]def __setitem__(self, index, value):self._items[index] = valuedef __str__(self):return str(self._items)# 使用示例
seq = MySequence([10, 20, 30])
print(seq[1])     # 输出: 20
seq[1] = 99       # 修改元素
print(seq)        # 输出: [10, 99, 30]

三.自定义容器继承内置容器

        在 Python 中,自定义容器可以通过继承内置容器(如 listdictset 等)来实现,这样可以复用内置容器的大部分功能,同时根据需求添加或修改特定的行为。以下分别介绍继承不同内置容器的示例及相关要点。

1.继承 list 实现自定义容器

class CustomList(list):def __init__(self, *args):super().__init__(*args)def append_unique(self, item):"""添加元素,但仅在元素不在列表中时添加"""if item not in self:self.append(item)return selfdef get_average(self):"""计算列表中所有数值元素的平均值"""if not self:return 0total = sum(num for num in self if isinstance(num, (int, float)))count = sum(isinstance(num, (int, float)) for num in self)return total / count if count > 0 else 0# 使用自定义列表
custom_list = CustomList([1, 2, 3])
custom_list.append_unique(4)
custom_list.append_unique(2)  # 不会重复添加
print(custom_list)  # 输出: [1, 2, 3, 4]
print(custom_list.get_average())  # 输出: 2.5

        要点解释:__init__ 方法:通过 super().__init__(*args) 调用父类 list 的初始化方法,确保自定义列表能像普通列表一样初始化。

        自定义方法append_unique 方法用于添加唯一元素,get_average 方法用于计算列表中数值元素的平均值。这些方法是在继承 list 原有功能基础上的扩展。

 2.继承 dict 实现自定义容器

class CustomDict(dict):def __init__(self, *args, **kwargs):super().__init__(*args, **kwargs)def get_default(self, key, default=0):"""获取键对应的值,如果键不存在则返回默认值,同时将默认值存入字典"""value = self.get(key, default)if key not in self:self[key] = defaultreturn value# 使用自定义字典
custom_dict = CustomDict({'a': 1, 'b': 2})
print(custom_dict.get_default('a'))  # 输出: 1
print(custom_dict.get_default('c'))  # 输出: 0
print(custom_dict)  # 输出: {'a': 1, 'b': 2, 'c': 0}

要点解释:__init__ 方法:同样通过 super().__init__(*args, **kwargs) 调用父类 dict 的初始化方法。

自定义方法get_default 方法类似于 dict 的 get 方法,但会在键不存在时将默认值存入字典。

 继承 set 实现自定义容器:

class CustomSet(set):def __init__(self, *args):super().__init__(*args)def add_all(self, iterable):"""批量添加元素"""for item in iterable:self.add(item)return self# 使用自定义集合
custom_set = CustomSet([1, 2, 3])
custom_set.add_all([3, 4, 5])
print(custom_set)  # 输出: {1, 2, 3, 4, 5}

要点解释:__init__ 方法:调用父类 set 的初始化方法。

自定义方法add_all 方法用于批量添加元素,方便一次性处理多个元素的添加操作。

注意:

方法覆盖:在继承内置容器时,可以覆盖父类的方法,但要谨慎操作,确保不会破坏原有的功能逻辑。

性能考虑:虽然继承内置容器可以复用很多功能,但在某些情况下,自定义的操作可能会影响性能,需要进行性能测试和优化。

兼容性:要注意自定义容器与 Python 标准库和其他代码的兼容性,确保自定义容器的行为符合预期。

三.关键方法实现容器行为 

方法作用对应操作
__len__(self)返回长度len(obj)
__getitem__(self, key)获取元素obj[key]
__setitem__(self, key, value)设置元素obj[key] = value
__delitem__(self, key)删除元素del obj[key]
__contains__(self, item)成员检查item in obj
__iter__(self)返回迭代器for x in obj
__reversed__(self)反向迭代reversed(obj)

四、继承抽象基类 (ABC)

Python 的 collections.abc 模块提供了抽象基类,可确保自定义容器实现必要方法:

from collections.abc import MutableSequenceclass CustomList(MutableSequence):def __init__(self, data):self._data = list(data)def __len__(self):return len(self._data)def __getitem__(self, index):return self._data[index]def __setitem__(self, index, value):self._data[index] = valuedef __delitem__(self, index):del self._data[index]def insert(self, index, value):self._data.insert(index, value)

总结

  • 内置容器listtupledictset 等满足大部分需求。

  • 自定义容器:通过实现特殊方法(如 __getitem__)创建定制化容器。

  • 抽象基类:使用 collections.abc 确保容器行为一致性。

通过灵活组合这些特性,可以构建适合特定场景的高效数据结构。

http://www.lryc.cn/news/601815.html

相关文章:

  • Pinocchio 结合 CasADi 进行 IK 逆运动学及 Mujoco 仿真
  • 09_opencv_遍历操作图像像素
  • CIFAR100数据集实测-基于 AlexNet模型的压缩/Bagging/Boosting 探索
  • 人社部物联网安装调试员的实训平台
  • 深度学习(鱼书)day04--手写数字识别项目实战
  • 网络协议:计算机世界的“交通规则“与“社交礼仪“
  • java--WebSocket简单介绍
  • Flutter开发实战之性能优化与调试
  • 深入解析MIPI C-PHY (四)C-PHY物理层对应的上层协议的深度解析
  • Pytest 参数化进阶:掌握 parametrize 的多种用法
  • maven <dependencyManagement>标签的作用
  • AutoLabelImg:高效的数据自动化标注工具和下载
  • IndexedDB全面掌握:从入门到Odoo OWL框架实战
  • mac系统彻底删除mysql并重装
  • [AI8051U入门第十步]W5500-客户端
  • 全方位评测:11款主流指标平台优劣分析
  • FreeRTOS—队列集
  • 【Web APIs】JavaScript 节点操作 ⑩ ( 节点操作综合案例 - 动态生成表格案例 )
  • add新增管理员功能、BaseController类的简介--------示例OJ
  • 链表算法综合——重排链表
  • Webpack 和 Vite 的关键区别
  • 01人工智能中优雅草商业实战项目视频字幕翻译以及声音转译之底层处理逻辑阐述-卓伊凡|莉莉
  • J2EE模式---服务层模式
  • WAIC 2025 热点解读:如何构建 AI 时代的“视频神经中枢”?
  • Java面试题及详细答案120道之(081-100)
  • 零基础学习性能测试第五章:JVM性能分析与调优-多线程机制与运行原理
  • 【RAG技术权威指南】从原理到企业级应用实践
  • 蓝奏云网盘API 2.0
  • HCIE学习之路:路由引入
  • 比特币运行机制全解析:区块链、共识算法与数字黄金的未来挑战