################
# 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)]
05-11 04:03