举例可哈希序列去重
b=[1,2,3,1,2,5] def debque1(items): result=set() for item in items: if item not in result: yield item result.add(item) print(list(debque1(b))) #[1, 2, 3, 5]
举例不可哈希序列去重
a = [ {‘x‘:1, ‘y‘:2}, {‘x‘:1, ‘y‘:3}, {‘x‘:1, ‘y‘:2}, {‘x‘:2, ‘y‘:4}] def debque2(items,key=None): result=set() for item in items: val=item if key is None else key(item) if val not in result: yield item result.add(val) print(list(debque2(a,key=lambda item:(item["x"],item["y"])))) # [{‘x‘: 1, ‘y‘: 2}, {‘x‘: 1, ‘y‘: 3}, {‘x‘: 2, ‘y‘: 4}]
这方法利用了生成器,科普一下生成器
如果列表元素可以按照某种算法推算出来,那我们就可以在循环的过程中不断推算出后续的元素,这样就不必创建完整的list,从而节省大量的空间,所以zai在Python中,就出现了这种一边循环一边计算的机制,称为生成器:generator
生成器是迭代器的一种,使用yield返回值函数,每次调用yield会暂停,而可以使用next()函数和send()函数恢复生成器。
要创建一个generator,有很多种方法,第一种方法很简单,只有把一个列表生成式的[]中括号改为()小括号,就创建一个generator
# 列表生成式 lis = [x*x for x in range(10)] print(lis) # 生成器 generator_ex = (x*x for x in range(10)) print(generator_ex) # 结果: # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] # <generator object <genexpr> at 0x000002A4CBF9EBA0>
如果要一个个打印出来,可以通过next()函数获得generator的下一个返回值:
但是一般不这么做,正确的方法是使用for循环,因为generator也是可迭代对象
生成器函数:也是用def定义的,利用关键字yield一次性返回一个结果,阻塞,重新开始
生成器表达式:返回一个对象,这个对象只有在需要的时候才产生结果
为什么叫生成器函数?因为它随着时间的推移生成了一个数值队列。一般的函数在执行完毕之后会返回一个值然后退出,但是生成器函数会自动挂起,然后重新拾起急需执行,他会利用yield关键字关起函数,给调用者返回一个值,同时保留了当前的足够多的状态,可以使函数继续执行,生成器和迭代协议是密切相关的,可迭代的对象都有一个__next__()__成员方法,这个方法要么返回迭代的下一项,要买引起异常结束迭代。
# 函数有了yield之后,函数名+()就变成了生成器 # return在生成器中代表生成器的中止,直接报错 # next的作用是唤醒并继续执行 # send的作用是唤醒并继续执行,发送一个信息到生成器内部 ‘‘‘生成器‘‘‘ def create_counter(n): print("create_counter") while True: yield n print("increment n") n +=1 gen = create_counter(2) print(gen) print(next(gen)) print(next(gen)) 结果: <generator object create_counter at 0x0000023A1694A938> create_counter 2 increment n 3 Process finished with exit code 0
生成器表达式来源于迭代和列表解析的组合,生成器和列表解析类似,但是它使用尖括号而不是方括号
>>> # 列表解析生成列表 >>> [ x ** 3 for x in range(5)] [0, 1, 8, 27, 64] >>> >>> # 生成器表达式 >>> (x ** 3 for x in range(5)) <generator object <genexpr> at 0x000000000315F678> >>> # 两者之间转换 >>> list(x ** 3 for x in range(5)) [0, 1, 8, 27, 64]
感谢:https://www.cnblogs.com/wj-1314/p/8490822.html
原文:https://www.cnblogs.com/zzy-9318/p/10414367.html