#一日一库——itertools
from itertools import count, chain
import operator
#=======count=========
#count 实现了一个无限累加器,默认从0开始累加,当然我可以给count一个默认初始值
#从这个初始值开始累加
# count 内部实现了__iter__ __next__ 因此它是一个迭代器,可以用通过next来迭代
c = count()
print(c)
print(next(c)) #0 第一次next返回默认值
print(next(c)) #1 以后则累加
#因此我可以for _ in c 产出无限大小值,但是不建议这样做,容易造成编辑器的卡死
c1 = count(10)
print(next(c1))
cc = c1.__next__
print(cc()) #11
print(cc()) #12
#=======chain=========
#遍历所有的可迭代的对象,直到所有参数可迭代对象被遍历完,并返回一个生成器;
a = chain('a我c', 'cde', 'fgh')
print(a)
# 可以通过chain.from_iterables();
print(list(a.from_iterable(['ac', 'df']))) #['a', 'c', 'd', 'f
from itertools import repeat, cycle, takewhile, dropwhile, filterfalse
#=============repeat==============
#这个函数没啥好说的,简单粗暴,参数2为要重复参数1的次数,返回一个迭代器
print(list(repeat(2, 10)))
print(list(repeat('ab', 10)))
#==============takewhile==========
#参数1为一个条件函数,常用lambda简写
print(list(takewhile(lambda x: x<5, [1, 2, 4, 5, 3, 4, 10])))
#===============dropwhile==========
#参数1同样为一个条件函数,当条件满足是会丢弃迭代对象中满足条件的对象
#值得注意的是只会丢弃第一个满足的对象之前的数值,之后的数值即使满足条件也会被输出,有点绕口
#看下源码
print(list(dropwhile(lambda x: x<5, [1, 2, 4, 5, 3, 4, 10]))) #print 5, 3, 4, 10
'''
def dropwhile(predicate, iterable):
# dropwhile(lambda x: x<5, [1,4,6,4,1]) --> 6 4 1
iterable = iter(iterable)
for x in iterable:
if not predicate(x):
yield x
break
for x in iterable:
yield x
'''
# 可以看到当遍历对象满足条件函数时,会跳出循环,由于遍历的是同一迭代器,迭代器会保存当前
# 迭代下标,跳出循环后会继续迭代后续的对象
#===============cycle===============
#for _ in cycle('ABC'):
# print(_)
#无脑的循环输出就完事了
#======================filterfalse===========
#类似之前的dropwhile、takewhile 都是根据条件函数,进行筛选数据
#看源码
'''
def filterfalse(predicate, iterable):
# filterfalse(lambda x: x%2, range(10)) --> 0 2 4 6 8
if predicate is None:
predicate = bool
for x in iterable:
if not predicate(x):
yield x
'''