hashable/iterable与orderable
################
# hashable协议 #
################ # 一个对象能被称为hashable,它必须实现__hash__与_eq__方法:
>>>{[1,2,3]} # TypeError: unhashable type: 'list'
>>>{{'Justin':123456}} # TypeError: unhashable type: 'dict'
>>>{{1,2,3}} # TypeError: unhashable type: 'set' # 虽然p1与p3代表的是相同的坐标,但是集合中两个都收纳了,这是因为p1和p3使用默认的__hash__()获取的hash值不同
class Point:
def __init__(self,x,y):
self.x=x
self.y=y
def __repr__(self):
return 'Point({},{})'.format(self.x,self.y)
p1=Point(1,1)
p2=Point(2,2)
p3=Point(1,1)
ps={p1,p2,p3}
print(ps) # 显示{Point(1,1), Point(2,2), Point(1,1)} # 如果想让集合能提出代表相同坐标的Point对象,必须自行实现__eq__()与__hash__()方法
class Point:
def __init__(self,x,y):
self.x=x
self.y=y
def __eq__(self, other):
if hasattr(other,'x') and hasattr(other,'y'):
return self.x == other.x and self.y ==other.y
return False
def __hash__(self):
return 41 * (41+self.x)+self.y
def __str__(self):
return self.__repr__()
def __repr__(self):
return 'Point({},{})'.format(self.x,self.y)
p1=Point(1,1)
p2=Point(2,2)
p3=Point(1,1)
ps={p1,p2,p3}
print(ps) # 显示{Point(1,1), Point(2,2)} ################
# iterable协议 #
################ # 具有__iter__()方法的对象,就是一个iterable(可迭代的)对象
# 生成器也是一种迭代器,对于大部分的迭代需求,使用yield语句创建生成器会比较简单和直接
def cycle(elems):
while True:
for elem in elems:
yield elem
abcd_gen=cycle(('abcd'))
print(next(abcd_gen))
print(next(abcd_gen))
print(next(abcd_gen))
print(next(abcd_gen))
print(next(abcd_gen)) # 实现__iter__()
class Repeat:
def __init__(self,elem,n):
self.elem=elem
self.n=n
def __iter__(self):
elem=self.elem
n=self.n
class _Iter:
def __init__(self):
self.count=0
def __next__(self):
if self.count < n:
self.count += 1
return elem
else:
raise StopIteration
def __iter__(self):
return self
return _Iter()
for elem in Repeat('A',5):
print(elem,end=' ') # 使用itertools模块
# 在Python标准链接库中提供了itertools模块,当中有许多函数可以谢谢胡创建迭代器和生成器
import itertools
print(list(itertools.repeat('A',10))) #['A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A']
print(list(itertools.accumulate([1,2,3,4,5]))) # [1, 3, 6, 10, 15]
print(list(itertools.accumulate([1,2,3,4,5],int.__mul__))) # [1, 2, 6, 24, 120]
print((list(itertools.chain('ABC',[1,2,3])))) # ['A', 'B', 'C', 1, 2, 3]
print(list(itertools.chain.from_iterable(['ABC',[1,2,3]]))) # ['A', 'B', 'C', 1, 2, 3]
print(list(itertools.chain.from_iterable([[9,8,6],[1,2,3]]))) #[ 9, 8, 6, 1, 2, 3]
print(list(itertools.dropwhile(lambda x:x < 5,[1,4,6,4,1]))) # [6, 4, 1]
print(list(itertools.takewhile(lambda x:x < 5,[1,4,6,4,1]))) # [1, 4]
print(list(itertools.filterfalse(lambda x:x % 2,[1,2,3,4]))) # [2, 4] # 有时候可能需要按某个键进行分类,可以使用itertools的groupby函数:
name=['Justin','Monica','Irene','Pika','caterpillar']
group_by_name=itertools.groupby(name,lambda name:len(name))
for length,group in group_by_name:
print(length,list(group))
# 6 ['Justin', 'Monica']
# 5 ['Irene']
# 4 ['Pika']
# 11 ['caterpillar'] ################
# orderable协议 #
################ # 如果希望使用自定义类型的sorted()或者使用列表的sort()时有默认的排序定义,那么必须实现__lt__()方法
class Customer:
def __init__(self,name,symbol,age):
self.name=name
self.symbol=symbol
self.age=age
def __lt__(self, other):
return self.name < other.name
def __str__(self):
return "Customer('{name}','{symbol}'".format(**vars(self))
def __repr__(self):
return self.__str__()
customers=[
Customer('Justin','A',40),
Customer('Irene','C',8),
Customer('Monica','B',37),
]
print(sorted(customers)) # [Customer('Irene','C', Customer('Justin','A', Customer('Monica','B'] # opertor模块的itemgetter和attrgetter,前者可以针对具有索引的结构,后者可以针对对象的属性
# 下面是使用itemgetter的示范:
from operator import itemgetter
custormers=[('Justin','A',40),('Irene','C',8),('Monica','B',37),]
print(sorted(custormers,key=itemgetter(0))) # [('Irene', 'C', 8), ('Justin', 'A', 40), ('Monica', 'B', 37)]
print(sorted(custormers,key=itemgetter(1))) # [('Justin', 'A', 40), ('Monica', 'B', 37), ('Irene', 'C', 8)]
print(sorted(custormers,key=itemgetter(2))) # [('Irene', 'C', 8), ('Monica', 'B', 37), ('Justin', 'A', 40)] # 下面是使用attrgetter的示范:
from operator import attrgetter
class Customer:
def __init__(self,name,symbol,age):
self.name=name
self.symbol=symbol
self.age=age
def __repr__(self):
return "Customer('{name}','{symbol}',{age})".format(**vars(self))
customers=[
Customer('Justin','A',40),
Customer('Irene','C',8),
Customer('Monica','B',37),
]
print(sorted(customers,key=attrgetter('name')))
# [Customer('Irene','C',8), Customer('Justin','A',40), Customer('Monica','B',37)]
print(sorted(customers,key=attrgetter('symbol')))
# [Customer('Justin','A',40), Customer('Monica','B',37), Customer('Irene','C',8)]
print(sorted(customers,key=attrgetter('age')))
# [Customer('Irene','C',8), Customer('Monica','B',37), Customer('Justin','A',40)]
hashable/iterable与orderable的更多相关文章
- graph_tool源码及其注释
#! /usr/bin/env python # -*- coding: utf-8 -*- # # graph_tool -- a general graph manipulation python ...
- Python创建容器和集合之源码分析
_collections_abc.py文件中提供了许多抽象基类,这些类将集合分解成许多互相独立的属性集 __all__ = ["Awaitable", "Coroutin ...
- python(七):元类与抽象基类
一.实例创建 在创建实例时,调用__new__方法和__init__方法,这两个方法在没有定义时,是自动调用了object来实现的.python3默认创建的类是继承了object. class A(o ...
- python高级(三)—— 字典和集合(泛映射类型)
本文主要内容 可散列类型 泛映射类型 字典 (1)字典推导式 (2)处理不存在的键 (3)字典的变种 集合 映射的再讨论 python高级——目录 文中代码均放在github上:https://git ...
- Python 3 初探,第 2 部分: 高级主题
Python 3 是 Guido van Rossum 功能强大的通用编程语言的最新版本.它虽然打破了与 2.x 版本的向后兼容性,但却清理了某些语法方面的问题.本文是这个由两部分组成的系列文章中的第 ...
- Effective Python之编写高质量Python代码的59个有效方法
这个周末断断续续的阅读完了<Effective Python之编写高质量Python代码 ...
- collections 中 typing 中对象的引用
from typing import ( Callable as Callable, Container as Container, Hashable as Hashable, Iterable as ...
- 编写高质量Python代码的59个有效方法
Python学习资料或者需要代码.视频加Python学习群:960410445 1. 用Pythonic方式思考 第一条:确认自己使用的Python版本 (1)有两个版本的python处于活跃状态,p ...
- [python数据结构] hashable, list, tuple, set, frozenset
学习 cs212 unit4 时遇到了 tuple, list, set 同时使用的问题,并且进行了拼接.合并操作.于是我就被弄混了.所以在这里进行一下总结. hashable and unhasha ...
随机推荐
- vue-webpack项目本地开发环境设置代理解决跨域问题
前言: 一般跨域问题只要后端配置好的话,是不需要前端做处理的,但也不能保证你遇到的所有后端都能很好的处理这个问题,这个时候可能就需要前端设置代理解决这个问题了. 配置方法: 1. config/ind ...
- swift - 添加定时器
mport UIKit /// 控制定时器的类 class ZDTimerTool: NSObject { /// 定时器 // private var timer: Timer? /// GCD定时 ...
- AngularJS——第7章 依赖注入
第7章 依赖注入 AngularJS采用模块化的方式组织代码,将一些通用逻辑封装成一个对象或函数,实现最大程度的复用,这导致了使用者和被使用者之间存在依赖关系. 所谓依赖注入是指在运行时自动查找依赖关 ...
- Tomcat登陆mysql的密码设置
在登陆mysql的密码和数据库密码不一致时,可以修改Mysql数据库密码或者修改连接Mysql的配置文件: 1.修改连接Tomcat里连接Mysql的配置文件 需要修改两个配置文件 ,一个是在tom ...
- go语言中的反射reflect
package main; import ( "fmt" "reflect" ) //反射refection //反射使用TypeOf和ValueOf函数从接口 ...
- Struts框架之结果页面的跳转
1. 结果页面存在两种方式 * 全局结果页面(有很多时候我们会跳转到同一页面,所以我们可以配置一个全局结果页面,不管什么情况都会跳转到这个页面) > 条件:如果<package>包中 ...
- Linux安装命令出现如下错误:cannot find a valid baseurl for repo :base/7x86_64
今天刚回到家,在我的虚拟机上有安装了一个Linux系统,安装好之后,想要安装如下命令,yum install wget,yum install gcc,yum install vim,发现一个也没有安 ...
- Unknown type name 'NSString' 解决方案
今天看到个问题,编辑工程提示Unknown type name 'NSString',如下图 导致出现异常的原因是是因为工程中添加了ZipArchive(第三方开源解压缩库) 一般情况下出现“Unkn ...
- MySQL学习笔记-事务相关话题
事务机制 事务(Transaction)是数据库区别于文件系统的重要特性之一.事务会把数据库从一种一致状态转换为另一个种一致状态.在数据库提交工作时,可以确保其要么所有修改都已经保存了,要么所有修改都 ...
- BUG(0):用某位表示特定属性
用某个bit表示特定属性通常有两种方式: 1.指定某个特定的value #define _PAGE_VALID 0x0001 0bit 为 1 时表示此时的page entry是有效的 用法如下,此时 ...