微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Python 迭代器工具包【推荐】

  原文:https://git.io/pytips

  0x01 介绍了迭代器的概念,即定义了 __iter__() __next__() 方法的对象,或者通过 yield 简化定义的“可迭代对象”,而在一些函数式编程语言(见 0x02 Python 中的函数式编程)中,类似的迭代器常被用于产生特定格式的列表(或序列),这时的迭代器更像是一种数据结构而非函数(当然在一些函数式编程语言中,这两者并无本质差异)。Python 借鉴了 APL,Haskell,and SML 中的某些迭代器的构造方法,并在 itertools 中实现(该模块是通过 C 实现,源代码:/Modules/itertoolsmodule.c)。

  itertools 模块提供了如下三类迭代器构建工具:

  无限迭代

  整合两序列迭代

  组合生成

  1. 无限迭代

  所谓无限(infinite)是指如果你通过 for...in... 的语法对其进行迭代,将陷入无限循环,包括

  

count(start,[step])

  cycle(p)

  repeat(elem [,n])

  从名字大概可以猜出它们的用法,既然说是无限迭代,我们自然不会想要将其所有元素依次迭代取出,而通常是结合 map/zip 等方法,将其作为一个取之不尽的数据仓库,与有限长度的可迭代对象进行组合操作:

  

from itertools import cycle,count,repeat
print(count.__doc__)
  count(start=0,step=1) --> count object
  Return a count object whose .__next__() method returns consecutive values.
  Equivalent to:
  def count(firstval=0,step=1):
  x = firstval
  while 1:
  yield x
  x += step
  counter = count()
  print(next(counter))
  print(next(counter))
  print(list(map(lambda x,y: x+y,range(10),counter)))
  odd_counter = map(lambda x: 'Odd#{}'.format(x),count(1,2))
  print(next(odd_counter))
  print(next(odd_counter))

  0

  1

  [2,4,6,8,10,12,14,16,18,20]

  Odd#1

  Odd#3

  print(cycle.__doc__)

  cycle(iterable) --> cycle object

  Return elements from the iterable until it is exhausted.

  Then repeat the sequence indefinitely.

  cyc = cycle(range(5))

  print(list(zip(range(6),cyc)))

  print(next(cyc))

  print(next(cyc))

  [(0,0),(1,1),(2,2),(3,3),(4,4),(5,0)]

  1

  2

  print(repeat.__doc__)

  repeat(object [,times]) -> create an iterator which returns the object

  for the specified number of times. If not specified,returns the object

  endlessly.

  print(list(repeat('Py',3)))

  rep = repeat('p')

  print(list(zip(rep,'y'*3)))

  ['Py','Py','Py']

  [('p','y'),('p','y')]

  2. 整合两序列迭代

  所谓整合两序列,是指以两个有限序列为输入,将其整合操作之后返回为一个迭代器,最为常见的 zip 函数就属于这一类别,只不过 zip 是内置函数。这一类别完整的方法包括

 

 accumulate()

  chain()/chain.from_iterable()

  compress()

  dropwhile()/filterfalse()/takewhile()

  groupby()

  islice()

  starmap()

  tee()

  zip_longest()

  这里就不对所有的方法一一举例说明了,如果想要知道某个方法用法,基本通过 print(method.__doc__) 就可以了解,毕竟 itertools 模块只是提供了一种快捷方式,并没有隐含什么深奥的算法。这里只对下面几个我觉得比较有趣的方法进行举例说明。

  

from itertools import cycle,compress,islice,takewhile,count

  # 这三个方法(如果使用恰当)可以限定无限迭代

  # print(compress.__doc__)

  print(list(compress(cycle('PY'),[1,1,0])))

  # 像操作列表 l[start:stop:step] 一样操作其它序列

  # print(islice.__doc__)

  print(list(islice(cycle('PY'),2)))

  # 限制版的 filter

  # print(takewhile.__doc__)

  print(list(takewhile(lambda x: x < 5,count())))

  ['P','P']

  ['P','Y']

  [0,2,3,4]

  from itertools import groupby

  from operator import itemgetter

  print(groupby.__doc__)

  for k,g in groupby('AABBC'):

  print(k,list(g))

  db = [dict(name='python',script=True),  dict(name='c',script=False),  dict(name='c++',  dict(name='ruby',script=True)]

  keyfunc = itemgetter('script')

  db2 = sorted(db,key=keyfunc) # sorted by `script'

  for isScript,langs in groupby(db2,keyfunc):

  print(','.join(map(itemgetter('name'),langs)))

  groupby(iterable[,keyfunc]) -> create an iterator which returns

  (key,sub-iterator) grouped by each value of key(value).

  A ['A','A']

  B ['B','B']

  C ['C']

  c,c++

  python,ruby

  from itertools import zip_longest

  # 内置函数 zip 以较短序列为基准进行合并,

  # zip_longest 则以最长序列为基准,并提供补足参数 fillvalue

  # Python 2.7 中名为 izip_longest

  print(list(zip_longest('ABCD','123',fillvalue=0)))

  [('A','1'),('B','2'),('C','3'),('D',0)]

  3. 组合生成

  关于生成器的排列组合: 

product(*iterables,repeat=1):两输入序列的笛卡尔乘积

  permutations(iterable,r=None):对输入序列的完全排列组合

  combinations(iterable,r):有序版的排列组合

  combinations_with_replacement(iterable,r):有序版的笛卡尔乘积

  from itertools import product,permutations,combinations,combinations_with_replacement

  print(list(product(range(2),range(2))))

  print(list(product('AB',repeat=2)))

  [(0,(0,1)]

  [('A','A'),('A','B'),'B')]

  print(list(combinations_with_replacement('AB',2)))

  [('A','B')]

  # 赛马问题:4匹马前2名的排列组合(A^4_2)

  print(list(permutations('ABCDE','C'),'D'),'E'),('E','D')]

  # 彩球问题:4种颜色的球任意抽出2个的颜色组合(C^4_2)

  print(list(combinations('ABCD','D')]

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


使用爬虫利器 Playwright,轻松爬取抖查查数据 我们先分析登录的接口,其中 url 有一些非业务参数:ts、he、sign、secret。 然后根据这些参数作为关键词,定位到相关的 js 代码。 最后,逐步进行代码的跟踪,发现大部分的代码被混淆加密了。 花费了大半天,来还原这些混淆加密的代码
轻松爬取灰豚数据的抖音商品数据 调用两次登录接口实现模拟登录 我们分析登录接口,发现调用了两次不同的接口;而且,需要先调用 https://login.huitun.com/weChat/userLogin,然后再调用 https://dyapi.huitun.com/userLogin 接口。 登
成功绕过阿里无痕验证码,一键爬取飞瓜数据 飞瓜数据的登录接口,接入了阿里云的无痕验证码;通过接口方式模拟登录,难度比较高。所以,我们使用自动化的方式来实现模拟登录,并且获取到 cookie 数据。 [阿里无痕验证码] https://help.aliyun.com/document_detail/1
一文教你从零开始入门蝉妈妈数据爬取,成功逆向破解数据加密算法 通过接口进行模拟登录 我们先通过正常登录的方式,分析对应的登录接口。通过 F12 打开谷歌浏览器的调试面板,可以看到登录需要传递的一些参数;其中看到密码是被加密了。 不过我们通过经验可以大概猜测一下,应该是通过 md5 算法加密了。 接下
抽丝剥茧成功破解红人点集的签名加密算法 抽丝剥茧破解登录签名算法,成功实现模拟登录 headers = {} phone_num = &quot;xxxx&quot; password = &quot;xxxx&quot; md5_hash = hashlib.md5() md5_hash.upda
轻松绕过 Graphql 接口爬取有米有数的商品数据 有米有数数据的 API 接口,使用的是一种 API 查询语言 graphql。所有的 API 只有一个入口,具体的操作隐藏在请求数据体里面传输。 模拟登录,获取 sessionId 调用登录接口,进行模拟登录。 cookies = {} head
我最近重新拾起了计算机视觉,借助Python的opencv还有face_recognition库写了个简单的图像识别demo,额外定制了一些内容,原本想打包成exe然后发给朋友,不过在这当中遇到了许多小问题,都解决了,记录一下踩过的坑。 1、Pyinstaller打包过程当中出现warning,跟d
说到Pooling,相信学习过CNN的朋友们都不会感到陌生。Pooling在中文当中的意思是“池化”,在神经网络当中非常常见,通常用的比较多的一种是Max Pooling,具体操作如下图: 结合图像理解,相信你也会大概明白其中的本意。不过Pooling并不是只可以选取2x2的窗口大小,即便是3x3,
记得大一学Python的时候,有一个题目是判断一个数是否是复数。当时觉得比较复杂不好写,就琢磨了一个偷懒的好办法,用异常处理的手段便可以大大程度帮助你简短代码(偷懒)。以下是判断整数和复数的两段小代码: 相信看到这里,你也有所顿悟,能拓展出更多有意思的方法~
文章目录 3 直方图Histogramplot1. 基本直方图的绘制 Basic histogram2. 数据分布与密度信息显示 Control rug and density on seaborn histogram3. 带箱形图的直方图 Histogram with a boxplot on t