python 文本处理2

接上文,我们定义了判断某行是否file copy,或者file overwrite的两个函数,事实上我们如果使用

startswith函数代替slice,会更稳定。从函数式编程角度,我们给出下面几个表达式:
      isRegDBRoot = lambda line: line[:11]=='RegDB Root:'
      isRegDBKey = lambda line: line[:10]=='RegDB Key:'
      isRegDBVal = lambda line: line[:10]=='RegDB Val:'
有了这三个更加紧凑的函数,我们给出之前方法的函数式编程写法;
      lines = open(r'd:\python22\install.log').readlines()
      regroot_lines = filter(isRegDBRoot, lines)
如果,你想通过多个选择标准来选择相应的行,那么函数式的写法就会显得笨拙。
我们可以根据相似的思路写出一个给定要求对应的过滤函数如下:
 #*--------------- Find the RegDB lines ------------------#
      def isAnyRegDB(line):
          if   line[:11]=='RegDB Root:': return 1
          elif line[:10]=='RegDB Key:':  return 1
          elif line[:10]=='RegDB Val:':  return 1
          else:                          return 0

但是,如果需求变成了其他的组合呢?显然依据这个思路,我们必须为另外的组合写更多的组合,这种组合是爆炸性的增长的。。。另外的思路是通过嵌套过滤函数来达到:
 #*------------- Filter on two line predicates -----------#
      shortline = lambda line: len(line) < 25
      short_regvals = filter(shortline, filter(isRegDBVal, lines))
这样的思路写出的程序比较容易排错,该函数使用了两个已有的函数来生成新的程序。但是一个显而易见的问题是:这样的程序很难阅读。同样的问题也出现在map函数上。通常解决这样问题的方法是多增加一些循环和中间变量。。
根据函授式编程的思路,我们可以在不增加代码量的情况下解决上面描述的问题。
这里的关键点是:选择的生成一些高级别的组合函数:这里的高级别函数是指:那些接受函数作为输入,返回函数作为输出的函数。一级函数接受数据,返回数据。相对应的一个高级函数的输入和输出都是函数对象。这些函数对象将在未来被其他地方使用:高级函数的一个例子是;函数工厂,它返回一个或者一组函数对象。下面是一个加法函数工厂;

>>> def adder_factory(n):
      ...    return lambda m, n=n: m+n
      ...
      >>> add10 = adder_factory(10)
      >>> add10
      <function <lambda> at 0x00FB0020>
      >>> add10(4)
      14
      >>> add10(20)
      30
      >>> add5 = adder_factory(5)
      >>> add5(4)
      9
回到正题,我们提到用高级组合函数来解决前面提到的问题,这些高级函数通过接受一些函数,对这些函数对象进行操作从而合成其他的函数。下面是一个组合高级函数库:
#------------------- combinatorial.py -------------------#
      from operator import mul, add, truth
      apply_each = lambda fns, args=[]: map(apply, fns, [args]*len(fns))
      bools = lambda lst: map(truth, lst)
      bool_each = lambda fns, args=[]: bools(apply_each(fns, args))
      conjoin = lambda fns, args=[]: reduce(mul, bool_each(fns, args))
      all = lambda fns: lambda arg, fns=fns: conjoin(fns, (arg,))
      both = lambda f,g: all((f,g))
      all3 = lambda f,g,h: all((f,g,h))
      and_ = lambda f,g: lambda x, f=f, g=g: f(x) and g(x)
      disjoin = lambda fns, args=[]: reduce(add, bool_each(fns, args))
      some = lambda fns: lambda arg, fns=fns: disjoin(fns, (arg,))
      either = lambda f,g: some((f,g))
      anyof3 = lambda f,g,h: some((f,g,h))
      compose = lambda f,g: lambda x, f=f, g=g: f(g(x))
      compose3 = lambda f,g,h: lambda x, f=f, g=g, h=h: f(g(h(x)))
      ident = lambda x: x
这样通过使用这些高级组合函数:我们可以这样解决之前遇到的问题:

 #----- Some examples using higher-order functions -----#
      # Don't nest filters, just produce func that does both
      short_regvals = filter(both(shortline, isRegVal), lines)

      # Don't multiply ad hoc functions, just describe need
      regroot_lines = \
          filter(some([isRegDBRoot, isRegDBKey, isRegDBVal]), lines)

      # Don't nest transformations, make one combined transform
      capFlipNorm = compose3(upper, flip, normalize)
      cap_flip_norms = map(capFlipNorm, lines)
可以看出通过函数式编程方法,我们可以不仅获得更加精炼的代码,以及更好的可读性.
任何嵌套的filter 和map函数都可以通过高级组合函数进行化简,总的来说,函数式编程方法得到的代码量应该在常规方法代码量的一半。
这种高级组合函数的另外一个好处是;他们可以提供一整套的函数的布尔表达式。
  #*---------- Simple Boolean algebra of values ----------#
      satisfied = (this or that) and (foo or bar)
在文本处理环境下,这样的操作经常是一些predic函数的结果。如下:
  #*---------- Boolean algebra of return values ----------#
      satisfied = (thisP(s) or thatP(s)) and (fooP(s) or barP(s))
通过之前的高级组合函数,我们可以得到如下代码:
 #*------ Boolean algebra of composed functions ------#
      satisfiedP = both(either(thisP,thatP), either(fooP,barP))
精简如斯啊。
一些问题下次再翻译,睡了。

转载于:https://www.cnblogs.com/zhangsong/archive/2012/07/10/2585412.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/463584.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

iOStextField/textView在输入时限制emoji表情的输入

https://www.jianshu.com/p/5227e6aab4d4 2017.02.27 13:08* 字数 146 阅读 6109评论 6喜欢 14 又遇到输入框输入表情的情况了&#xff0c;之前写了一篇文章“UITextView/UITextField检测并过滤Emoji表情符号”http://www.jianshu.com/p/90d68e7e5d53,但是总觉得那两种方式都各…

声学发展史之——人工智能(AI)声学

引言最近接手了一个EOL (End of Line)的项目&#xff0c;用高斯混合模型GMM (Gaussian Mixture Model)作生产线上产品的质量检测。虽然提取特征的过程很痛苦&#xff0c;不过还是很有意思。也是因为兴趣&#xff0c;去年在Coursera上了吴恩达的Machine Learning&#xff0c;算是…

Mysql数据库存储原理

转载&#xff1a;https://blog.csdn.net/weixin_40612082/article/details/82179714 现在在做数据库服务器的开发工作&#xff0c;今天被问到存储过程&#xff0c;当时只是简单地回答了下&#xff0c;在网上搜索了下资料&#xff0c;才对存储过程有了新的认识。转载内容如下&a…

seo专题之开篇有益

想写这篇文章好久了.但一直不敢写,一怕自己技术有限误导了园子里的各位朋友.二怕自己文笔有限不能很好的表达自己的意图,但既然是抱着交流的态度来的,我还是愿意写一写这方面的文章与大家一起交流和分享,欢迎大家拍砖.做SEO没有什么高深技术可言,靠的是经验的不断累积,各位SEO高…

Rails不用localhost访问的时候很慢

修改文件/usr/lib/ruby/1.9.1/webrick/config.rb,找到:DoNotReverseLookup > nil&#xff0c;修改为:DoNotReverseLookup > true。转载于:https://blog.51cto.com/tianbymy/926589

一个application多个 URL

需求&#xff1a; 希望一个sharepoint网站&#xff0c;有多个网址去访问。例如&#xff1a;http://moss:8080/的网站&#xff0c;http://aphla.prismshareusa.int/ 和 http://aphla.carat.int/ 两个网站同时访问。 解决方法如下&#xff1a; 1&#xff09;创建DNS…

gcc/g++编译器的优化

gcc/g编译器的优化 gcc提供了从O0-O3以及Os这几种不同的优化级别供大家选择 O0是编译器默认的设置 (1)、-O1&#xff1a;它主要对代码的分支&#xff0c;常量以及表达式等进行优化 (2)、-O2&#xff1a;尝试更多的寄存器级的优化以及指令级的优化&#xff0c;它会在编译期间…

C#中Equals和==的区别 (面试官经常会问到)

首先对于值类型来说&#xff0c;并没有什么区别。区别只针对于引用类型。 一、值类型 1.对于值类型来说&#xff0c;两者比较的都是“内容”是否相同&#xff0c;也就是值是否相同&#xff08;值类型只有存在栈上&#xff09;。 二、引用类型 1.对于引用类型来说&#xff0c;本…

写的重采样文章被大佬看到了

他让我看重采样昨天写的重采样文章被一个大佬看到了&#xff0c;给我发了消息如下大佬是个技术原厂Linux方向的负责人&#xff0c;我在工作上遇到的好几次疑难杂症都是在他的指点下得到解决&#xff0c;而且平时讨论技术的时候&#xff0c;能感觉到他对技术问题理解很深。从他的…

根据IP地址获取主机名称

IP地址获得主机名称 1. 根据IP地址获得主机名称///<summary>///根据IP地址获得主机名称 ///</summary>///<param name"ip">主机的IP地址</param>///<returns>主机名称</returns>publicstringGetHostNameByIp(stringip) …

vector中的reserve() 与 resize()

resize()与reserve()都是vector容器中的方法&#xff1a; resize():改变了capacity()和size() reserve():增加了vector的capacity()&#xff0c;但是它的size()没有改变 #include <iostream> #include <stdio.h> #include <vector> #include<functiona…

【C++】考虑virtual函数以外的其他选择

假设你正在写一个视频游戏软件&#xff0c;游戏里有各种各样的人物&#xff0c;每个人物都有健康状态&#xff0c;而且不同的人物可能以不同的方式计算他们的健康指数&#xff0e;该如何设计游戏里的人物&#xff0c;主要如何提供一个返回人物健康指数的接口&#xff0e; 方法一…

不知道你们遇到这样的问题没?

最近在网上看到这样一个内容https://developer.horizon.ai/forumDetail/118363914936419003关于J5/J3/J2平台的底层软件地平线内部的释放计划和形式&#xff1f;您好&#xff1a;问题如题&#xff0c;我们当前在地平线J5平台展开进行的项目居多&#xff0c;跟贵司接触和合作的部…

shell脚本while read line的使用

#### 题目要求计算文档a.txt中每一行中出现的数字个数并且要计算一下整个文档中一共出现了几个数字。例如a.txt内容如下&#xff1a;12aa*lkjskdjalskdflkskdjflkjj我们脚本名字为 ncount.sh, 运行它时&#xff1a;bash ncount.sh a.txt输出结果应该为&#xff1a;20sum:2 ####…

boost::split()的使用方式

引用的头文件 <boost/algorithm/string.hpp> boost::split()函数用于切割string字符串&#xff0c;将切割之后的字符串放到一个std::vector<std::string> 之中&#xff1b; 有4个参数&#xff1a; 以boost::split(type, select_list, boost::is_any_of(",&…

Java中文与ASCII码的转换

今天在研究Java中编码的时候&#xff0c;看到了Java中ascii码的强大。写了一个CoderUtils.java&#xff0c;以后会扩展它。 package com.xingxd.study.test; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; /** * …

第四周:机器学习知识点回顾

前言&#xff1a; 讲真&#xff0c;复习这块我是比较头大的&#xff0c;之前的线代、高数、概率论、西瓜书、樱花书、NG的系列课程、李宏毅李沐等等等等…那可是花了三年学习佳实践下来的&#xff0c;现在一想脑子里就剩下几个名词就觉得废柴一个了&#xff0c;朋友们有没有同感…

移植linux内核到i.MX6ULL过程

本文描述移植NXP官方 linux 5.4 内核到i.MX6ULL开发板。一、NXP官方linux内核1. 下载 NXP官方linux仓库地址为&#xff1a;https://github.com/Freescale/linux-fslc/tree/5.4-2.1.x-imx。选择该分支下载zip包即可&#xff0c;不要整个仓库下载&#xff0c;太大了&#xff1a;2…

Go语言之进阶篇http服务器获取客户端的一些信息

1、http服务器获取客户端的一些信息 示例: package mainimport ("fmt""net/http" )//w, 给客户端回复数据 //r, 读取客户端发送的数据 func HandConn(w http.ResponseWriter, r *http.Request) {fmt.Println("r.Method ", r.Method)fmt.Println…

R学习之——R用于文本挖掘(tm包)

首先需要安装并加载tm包。 1、读取文本 x readLines("222.txt") 2、建立语料库 > rCorpus(VectorSource(x))> rA corpus with 7012 text documents 3、语料库输出&#xff0c;保存到硬盘 > writeCorpus(r) 4、查看语料库 > print(r) A corpus with 7012…