python入门系列十一(容器数据类型)

1.引言

python内置给我们提供了collections模块,在这个模块中实现了一些专有化容器,这些专有化容器针对通用内建容器:dict,list,set,tuple进行了很好的补充,方便在实际应用中使用。

你可以参考:docs.python.org/zh-cn/3.11/...

下面我通过几个示例做演示。

2.容器数据类型

2.1.命名元组

命名元组namedtuple,它是一个工厂函数,用于创建元组子类,子类字段可以有名称,该子类用于创建类元组对象。如是后:

  • 可以通过字段获取属性值
  • 可以通过索引获取属性值
  • 可以通过迭代获取值

基本示例:

python 复制代码
# 命名元组namedtuple基本示例
# 通过namedtuple创建一个命名元组类:Point
from collections import namedtuple
Point = namedtuple("Point",['x','y'])
# 通过Point实例化一个元组
p = Point(10,20)

# 访问p属性值
print(f"通过字段名称访问p的属性值:x is {p.x} and y is {p.y}")
print(f"通过原生索引方式访问p的属性值:x is {p[0]} and y is {p[1]}")

高级玩法:

python 复制代码
# 命名元组namedtuple高级玩法
# 通过namedtuple创建一个命名元组类:Point
from collections import namedtuple
Point = namedtuple("Point",['x','y'])

# 定义平面坐标系的两个点
p1 = Point(10,20)
p2 = Point(15,35)

# 在平面坐标系实现两个点相加,预期p3 = (25,55)
p3 = p1 + p2
print(f"相加后的p3是:{p3}")

# 输出结果不如预期,扩展一下吧
# 定义一个2D平面坐标系
class Point2D(Point):
    def __add__(self,other):
        return (self.x+other.x,self.y+other.y)

# 通过扩展后的Point2D,定义平面坐标系点
p4 = Point2D(10,20)
p5 = Point2D(15,35)

# 在平面坐标系实现两个点相加,预期p6 = (25,55)
p6 = p4 + p5
print(f"相加后的p6是:{p6}")

高级示例程序中,通过重写魔术方法,实现了平面坐标系两个点相加效果。关于python中的魔术方法,稍后详细介绍。

2.2.计数器

Counter是字典dict子类,有了它,我们可以在应用中轻松实现计数器功能。

python 复制代码
# 计数器Counter示例
from collections import Counter

# 定义计数器不同方式
# 定义空计数器
c1 = Counter()
c1['red'] = 1
print(f"颜色red当前计数值:{c1['red']}")

# 通过映射定义计数器
c2 = Counter({"red":1,"green":2})
print(f"颜色green当前计数值:{c2['green']}")

# 通过关键字定义计数器
c3 = Counter(blue=1,yellow=2)
print(f"颜色blue当前计数值:{c3['blue']}")

2.3.顺序字典

顺序字典是字典dict的子类,它具有专门用于重新排列字典顺序的方法 。在实际应用中,通过顺序字典可以很方便实现缓存系统。比如

最近更新缓存策略系统:

python 复制代码
# 最近更新缓存系统
from collections import Counter

# 定义扩展OrderedDict,实现最后更新缓存系统
class LastUpdatedOrderedDict(OrderedDict):
    'Store items in the order the keys were last added'

    def __setitem__(self, key, value):
        super().__setitem__(key, value)
        self.move_to_end(key)

# 实例化缓存系统
myCache = LastUpdatedOrderedDict()
myCache['a'] = '小王'
print(f"加入a后的缓存系统:{myCache}")

myCache['b'] = '老王'
print(f"加入b后的缓存系统:{myCache}")

LRU更新策略缓存系统:

python 复制代码
# LRU更新策略缓存系统
from collections import Counter
from time import time

class TimeBoundedLRU:
    "LRU Cache that invalidates and refreshes old entries."

    def __init__(self, func, maxsize=128, maxage=30):
        self.cache = OrderedDict()      # { args : (timestamp, result)}
        self.func = func
        self.maxsize = maxsize
        self.maxage = maxage

    def __call__(self, *args):
        if args in self.cache:
            self.cache.move_to_end(args)
            timestamp, result = self.cache[args]
            if time() - timestamp <= self.maxage:
                return result
        result = self.func(*args)
        self.cache[args] = time(), result
        if len(self.cache) > self.maxsize:
            self.cache.popitem(0)
        return result

2.4.子类化对象

collections模块中还提供了一系列以User开头的子类化对象,方便我们做二次扩展。比如玩一玩UserDict

python 复制代码
# 扩展实现自定义字典,当向字典中添加存在的key时,
# 改变字典默认覆盖行为,通过提示用户不要覆盖
from collections import UserDict

# 定义一个类,扩展UserDict
class MyDict(UserDict):
    def __setitem__(self,key,value):
        if key in self.data.keys():
            print(f"{key}已经在字典中存在,不需要覆盖!")
        else:
            self.data[str(key)] = value

# 实例化使用字典
dict1 = MyDict()
dict1['name']='小王'
dict1['age'] = 18

# name重复试试
dict1['name']='老王'

2.5.魔术方法

在以上容器数据类型示例中,我们都使用到一些一两个下划线开头,且以两个下划线结尾的方法。在python中,这类方法叫做魔术方法,为什么这么叫?就是因为通过它们我们可以像玩魔术一样玩转python。

言归正传,原生python给我们提供了两类接口:一类是基类,用于继承扩展;一类是魔术方法,用于重写。python中任何一个类,或者对象都可以通过dir方法看到它相应的魔术方法

python 复制代码
# 扩展实现自定义字典,当向字典中添加存在的key时,
# 改变字典默认覆盖行为,通过提示用户不要覆盖
from collections import UserDict

# 定义一个类,扩展UserDict
class MyDict(UserDict):
    def __setitem__(self,key,value):
        if key in self.data.keys():
            print(f"{key}已经在字典中存在,不需要覆盖!")
        else:
            self.data[str(key)] = value

# 实例化使用字典
dict1 = MyDict()

# 查看MyDict魔术方法
dir(MyDict)

通过重写这些魔术方法,可以改变扩展类的行为,从而完成业务需要。建议你可以多去试试!

相关推荐
python1562 分钟前
OpenWebUI新突破,MCPO框架解锁MCP工具新玩法
人工智能·语言模型·自然语言处理
墨绿色的摆渡人15 分钟前
pytorch小记(二十一):PyTorch 中的 torch.randn 全面指南
人工智能·pytorch·python
大叔_爱编程18 分钟前
p024基于Django的网上购物系统的设计与实现
python·django·vue·毕业设计·源码·课程设计·网上购物系统
一个天蝎座 白勺 程序猿26 分钟前
Python爬虫(29)Python爬虫高阶:动态页面处理与云原生部署全链路实践(Selenium、Scrapy、K8s)
redis·爬虫·python·selenium·scrapy·云原生·k8s
90后小陈老师27 分钟前
WebXR教学 09 项目7 使用python从0搭建一个简易个人博客
开发语言·python·web
weixin-WNXZ021839 分钟前
闲上淘 自动上货工具运行原理解析
爬虫·python·自动化·软件工程·软件需求
正在走向自律1 小时前
Conda 完全指南:从环境管理到工具集成
开发语言·python·conda·numpy·fastapi·pip·开发工具
东临碣石821 小时前
【AI论文】EnerVerse-AC:用行动条件来构想具身环境
人工智能
lqjun08271 小时前
PyTorch实现CrossEntropyLoss示例
人工智能·pytorch·python
心灵彼岸-诗和远方1 小时前
芯片生态链深度解析(三):芯片设计篇——数字文明的造物主战争
人工智能·制造