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

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.xdnf.cn/news/16589.html

相关文章:

  • SpringBoot多容器化实例实战
  • FFmpeg——参数详解
  • 墨者:通过手工解决SQL手工注入漏洞测试(MongoDB数据库)
  • C++学习(线程相关)
  • 负载均衡Haproxy
  • SABR-Net
  • uniapp input 聚焦时键盘弹起滚动到对应的部分
  • iOS安全和逆向系列教程 第21篇:iOS应用加密与混淆技术深度剖析
  • Java面试宝典:MySQL性能优化
  • 用 ESP32 和 LCD 轻松显示植物湿度
  • 第十八章:AI的“通感”:揭秘图、文、音的共同语言——CLIP模型
  • 系统整理Python的循环语句和常用方法
  • Keil MDK 嵌入式开发问题:Error: L6218E: Undefined symbol HAL_TIM_PWM_ConfigChannel
  • GIt学习——分布式版本控制工具
  • 设计模式(八)结构型:桥接模式详解
  • 设计模式(七)结构型:适配器模式详解
  • 【网络协议安全】任务15:DHCP与FTP服务全配置
  • 安装Selenium⾃动化
  • PiscCode使用OpenCV实现漂浮方块特效
  • 三种常用的抗锯齿
  • Java大数据面试实战:Hadoop生态与分布式计算
  • esp32s3创建rust工程 window成功mac
  • 结构化文本文档的内容抽取与版本重构策略
  • net8.0一键创建支持(Orm-Sqlite-MySql-SqlServer)
  • 【最新最完整】SpringAI-1.0.0开发MCP Server,搭建MCP Client 实战笔记(进阶+详细+完整代码)
  • Map(HashMap、LinkedHashMap、TreeMap)双列集合
  • 【机器学习深度学习】LLaMAFactory评估数据与评估参数解析
  • 《频率之光:危机降临》
  • 下载 | Win11 官方精简版,系统占用空间极少!(7月更新、Win 11 IoT物联网 LTSC版、适合老电脑安装使用)
  • 进度条制作--Linux知识的小应用