Pythonic|collections.namedtuple的使用和对 list 对象Pythonic的的操作

news/2024/10/17 14:18:42/

collections

collections是Python内建的一个集合模块,提供了许多有用的集合类和方法。

可以把它理解为一个容器,里面提供Python标准内建容器 dict , list , set , 和 tuple 的替代选择。

namedtuple() : 创建一个命名元组子类的工厂函数
deque :    高效增删改双向列表,类似列表(list)的容器,实现了在两端快速添加(append)和弹出(pop)
defaultdict : 当字典查询时,为key不存在提供一个默认值。
OrderedDict : 有序词典,就是记住了插入顺序
Counter : 计数功能

namedtuple() 命名元组

namedtuple(typename, field_names, *, rename=False, defaults=None, module=None)

参数

  • typename : 命名的名字,返回一个新的元组子类,名为 typename
  • field_names : 可以是一个[‘x’, ‘y’]这样的序列,也可以是’x, y’或者’x y’
  • rename :   python3.1添加,如果 rename 为真, 无效域名会自动转换成位置名。比如 [‘abc’, ‘def’, ‘ghi’, ‘abc’] 转换成 [‘abc’, ‘_1’, ‘ghi’, ‘_3’] , 消除关键词 def 和重复域名 abc 。
  • defaults :  python3.7添加, defaults 可以为 None 或者是一个默认值的 iterable(可迭代对象)。如果一个默认值域必须跟其他没有默认值的域在一起出现, defaults 就应用到最右边的参数。比如如果域名 [‘x’, ‘y’, ‘z’] 和默认值 (1, 2) ,那么 x 就必须指定一个参数值 ,y 默认值 1 , z 默认值 2 。
  • module :   python3.6添加,如果 module 值有定义,命名元组的 __module__属性值就被设置

 namedtuple使用


import collections
# 创建对象  我们定义了一个Point类型的包含x,y两个值的增强元祖类型
PointA = collections.namedtuple('Point', ['x', 'y'])
p = PointA(10, y=20)  # 可以使用关键字参数和位置参数初始化namedtuple
#注意这个p类型既是我们定义的Point也是tuple,而元祖是不可使用_make 赋值和_replace 更改值的
print(p)  # 直接打印 Point(x=10, y=20) 也可以获取单个内容 p.x p.y
p_list = [PointA(i, y=-i) for i in range(5)] #也可迭代生成一个list
print(p_list)  # [Point(x=0, y=0), Point(x=1, y=-1), Point(x=2, y=-2), Point(x=3, y=-3), Point(x=4, y=-4)]
print(len(p_list))  # 获取长度 5
print(p_list[0])  #  根据下标取  Point(x=0, y=0)
from random import choiceprint(choice(p_list))  # 随机取一个
print(p_list[:3])  # 取前三个
print(p_list[0::2])  # 取第0个 然后每隔2个取一个

这是一些对list操作的特殊方法,是Python 自有的对序列数据类型的一些操作

[print(p_item) for p_item in reversed(p_list)]  # 反向排序输出print(PointA("A", "B") in p_list)
print(PointA(0, 0) in p_list)
for p_item in sorted(p_list, key=lambda x: x.y):  #匿名函数 参数:算式表达式# 根据每个元素的y值排序,也可以写个函数自己定义一个,返回值根据返回值默认从小到大排print(p_item)

sorted() 函数对所有可迭代的对象进行排序操作。

sort 与 sorted 区别:

sort 是应用在 list 上的方法,sorted 可以对所有可迭代的对象进行排序操作。

list 的 sort 方法返回的是对已经存在的列表进行操作,而内建函数 sorted 方法返回的是一个新的 list,而不是在原来的基础上进行的操作。

sorted(iterable, key=None, reverse=False)  

参数说明:

  • iterable -- 可迭代对象。
  • key -- 用来进行比较的元素,可以是一个函数,也可以是一个类,也可以是其他的处理方法。只有一个参数,具体的函数的参数就是取自于可迭代对象中,指定可迭代对象中的一个元素来进行排序。
  • reverse -- 排序规则,reverse = True 降序 , reverse = False 升序(默认)。

返回值:

        返回重新排序的列表。

类中使用namedtuple

在类中使用 namedtuple 如果需要对这个类实例化的对象所有的对[]操作都操作到 类中定义的namedtuple  对象上,只需要在类中实现 __len__方法和__getitem__方法就好了

PointA = collections.namedtuple('Point', ['x', 'y'])
class PointList:def __init__(self):self._point = [PointA(i, y=-i) for i in range(5)]def __len__(self):   #上面列表推导式的 len函数本质就是这个len的实现return len(self._point)def __getitem__(self, position):  #上面后续其他对元素的操作 依赖于__getitem__# 也就是对这个类实例化对象的对[]的操作都给了self._point列表# 如[x]按下标取, random.choice,切片,迭代,sorted排序等return self._point[position]
point_list=PointList()
print(len(point_list))
print(collections.Counter(point_list))

优点是可以更加方便地利用 Python 的标准库,比如 random.choice 函
数,从而不用重新发明轮子。这都是由 __getitem__ 方法提供的 

好,我们这时候想打乱一下这个序列,我们知道有 random.shuffle 函
数可用

from random import shuffle
shuffle(point_list)

他会报错:TypeError: 'PointList' object does not support item assignment

('PointList' 对象不支持为元素赋值)。这个问题的原因是,shuffle 函数要调换集合中元素的位置,而 PointList只实现
了不可变的序列协议。可变的序列还必须提供 __setitem__ 方法。

class PointList:def __init__(self):self._point = [PointA(i, y=-i) for i in range(5)]def __len__(self):   #上面列表推导式的 len函数本质就是这个len的实现return len(self._point)def __getitem__(self, position):  #上面后续其他对元素的操作 依赖于__getitem__# 也就是对这个类实例化对象的对[]的操作都给了self._point列表# 如[x]按下标取, random.choice,切片,迭代,sorted排序等return self._point[position]def __setitem__(self, key, value):self._point[key]=value
point_list=PointList()
print(len(point_list))
# print(collections.Counter(point_list))from random import shuffle
shuffle(point_list)
print(point_list[:3])

定义__setitem__函数,它的参数为 self、key和 value。我们对self的_point根据key取到的元素改value。现在可以打乱 point_list了,因为 PointList实现了可变序列协议所需的方法。

当然我们也可以定义一个方法,然后利用python动态语言的猴子特性,可以在外面直接赋值给PointList类的__setitem__属性

def set_point(p, key, value): p._point[key] = value
PointList.__setitem__ = set_point

这里的关键是point_list对象有一个名为 _point的属性,而且 _point的值必须是可变序列。然后,我们实现特殊方法 __setitem__,从而把它依附到 PointList类上。


http://www.ppmy.cn/news/55608.html

相关文章

博世中国创新软件开发中心 BCSC

Bosch China Innovation and Software Development Campus 博世中国创新软件开发中心 BCSCWelcome all CSDN friends to contact me via private message,期待优秀的你,投递卓越CV,join BCSC,一起擎软件! 拓未来&#…

IDE - Android Studio/Xcode历史版本下载

文章目录 前言Android Studio1. 历史版本下载2. 文件完整性校验 Xcode1. 历史版本下载2. 网络环境模拟工具2.1 下载2.2 安装2.3 卸载 最后 前言 最近升级开发工具老是遇到各种兼容性问题导致需要降回老版本,Xcode历史版本下载方便倒还好,Android Studio…

opengauss编译和使用oracle_fdw

opengauss虽然继承自postgresql9.2,但由于做了魔改,网上通用的从oracle_fdw源码编译安装到postgresql的方法,是否成功的应用到opengauss,并不一定,今天试了一下,参照opengauss官网文档(其实写的…

Spring 管理 Bean-IOC--基于注解配置 bean

目录 Spring 管理 Bean-IOC--基于注解配置 bean ● 基本介绍 ● 组件注解的形式有 代码演示--了解注解 UserDao UserService UserAction MyComponent 配置 beans.xml 注意 测试 注意事项和细节说明 自动装配 基本说明 应用实例需求 UserService UserAction 配置…

Linux系统主要目录

Linux系统中主要的目录,其中某些目录在不同的Linux发行版中可能有所不同。 目录名称作用bin存放常用命令boot存放引导系统相关的文件dev存放设备文件etc存放系统配置文件home存放用户的主目录lib存放系统共享库lib64存放系统共享库,用于64位系统lostfou…

bito ai 使用vue2 写一个弹框插件

使用vue2,写一个消息弹框的插件,使用vue.use()导入插件,要求插件全局可使用,使用this就可以在vue页面调用,这个消息弹窗有两个按钮,一个取消,一个确定,点击取消消息提示消失&#xf…

解决安卓中RecyclerView当一项被点击之后,后面每间隔相同的一段都会有其它项被点击

文章目录 问题描述缘由解决办法 1:提高缓存容量解决办法 2:每次在初始化视图数据之前重置视图数据解决办法 3:优化设计,不在视图中储存数据 问题描述 安卓开发会有很多很多莫名其妙的坑。笔者在使用 RecyclerView 的过程中&#x…

PHP面试宝典之Redis下篇

redis主从同步? 全量同步: 什么时候进行全量同步? 1:从节点第一次连接主节点时 2:从节点断开时间太久,日志中的offset被覆盖时 全量同步的过程? 1:从节点请求增量同步 2&…