函数式编程之pipeline——很酷有没有_djph26741的博客-程序员宅基地

技术标签: python  awk  shell  

Pipeline

pipeline 管道借鉴于Unix Shell的管道操作——把若干个命令串起来,前面命令的输出成为后面命令的输入,如此完成一个流式计算。(注:管道绝对是一个伟大的发明,他的设哲学就是KISS – 让每个功能就做一件事,并把这件事做到极致,软件或程序的拼装会变得更为简单和直观。这个设计理念影响非常深远,包括今天的Web Service,云计算,以及大数据的流式计算等等)

比如,我们如下的shell命令:

1
ps  auwwx |  awk  '{print $2}'  sort  -n |  xargs  echo

如果我们抽象成函数式的语言,就像下面这样:

1
xargs(  echo, sort(n, awk( 'print $2' , ps(auwwx)))  )

也可以类似下面这个样子:

1
pids  =  for_each(result, [ps_auwwx, awk_p2, sort_n, xargs_echo])

好了,让我们来看看函数式编程的Pipeline怎么玩?

我们先来看一个如下的程序,这个程序的process()有三个步骤:

1)找出偶数。
2)乘以3
3)转成字符串返回

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
def  process(num):
     # filter out non-evens
     if  num  %  2  ! =  0 :
         return
     num  =  num  *  3
     num  =  'The Number: %s'  %  num
     return  num
 
nums  =  [ 1 2 3 4 5 6 7 8 9 10 ]
 
for  num  in  nums:
     print  process(num)
 
# 输出:
# None
# The Number: 6
# None
# The Number: 12
# None
# The Number: 18
# None
# The Number: 24
# None
# The Number: 30

我们可以看到,输出的并不够完美,另外,代码阅读上如果没有注释,你也会比较晕。下面,我们来看看函数式的pipeline(第一种方式)应该怎么写?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
def  even_filter(nums):
     for  num  in  nums:
         if  num  %  2  = =  0 :
             yield  num
def  multiply_by_three(nums):
     for  num  in  nums:
         yield  num  *  3
def  convert_to_string(nums):
     for  num  in  nums:
         yield  'The Number: %s'  %  num
 
nums  =  [ 1 2 3 4 5 6 7 8 9 10 ]
pipeline  =  convert_to_string(multiply_by_three(even_filter(nums)))
for  num  in  pipeline:
     print  num
# 输出:
# The Number: 6
# The Number: 12
# The Number: 18
# The Number: 24
# The Number: 30

我们动用了Python的关键字 yield,这个关键字主要是返回一个Generator,yield 是一个类似 return 的关键字,只是这个函数返回的是个Generator-生成器。所谓生成器的意思是,yield返回的是一个可迭代的对象,并没有真正的执行函数。也就是说,只有其返回的迭代对象被真正迭代时,yield函数才会正真的运行,运行到yield语句时就会停住,然后等下一次的迭代。(这个是个比较诡异的关键字)这就是lazy evluation。

好了,根据前面的原则——“使用Map & Reduce,不要使用循环”,那我们用比较纯朴的Map & Reduce吧。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def  even_filter(nums):
     return  filter ( lambda  x: x % 2 = = 0 , nums)
 
def  multiply_by_three(nums):
     return  map ( lambda  x: x * 3 , nums)
 
def  convert_to_string(nums):
     return  map ( lambda  x:  'The Number: %s'  %  x,  nums)
 
nums  =  [ 1 2 3 4 5 6 7 8 9 10 ]
pipeline  =  convert_to_string(
                multiply_by_three(
                    even_filter(nums)
                )
             )
for  num  in  pipeline:
     print  num

但是他们的代码需要嵌套使用函数,这个有点不爽,如果我们能像下面这个样子就好了(第二种方式)。

1
2
3
pipeline_func(nums, [even_filter,
                      multiply_by_three,
                      convert_to_string])

那么,pipeline_func 实现如下:

1
2
3
4
def  pipeline_func(data, fns):
     return  reduce ( lambda  a, x: x(a),
                   fns,
                   data)

好了,在读过这么多的程序后,你可以回头看一下这篇文章的开头对函数式编程的描述,可能你就更有感觉了。

最后,我希望这篇浅显易懂的文章能让你感受到函数式编程的思想,就像OO编程,泛型编程,过程式编程一样,我们不用太纠结是不是我们的程序就是OO,就是functional的,我们重要的品味其中的味道

参考

补充:评论中redraiment这个评论大家也可以读一读。

感谢谢网友S142857 提供的shell风格的python pipeline:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class  Pipe( object ):
     def  __init__( self , func):
         self .func  =  func
 
     def  __ror__( self , other):
         def  generator():
             for  obj  in  other:
                 if  obj  is  not  None :
                     yield  self .func(obj)
         return  generator()
 
@Pipe
def  even_filter(num):
     return  num  if  num  %  2  = =  0  else  None
 
@Pipe
def  multiply_by_three(num):
     return  num * 3
 
@Pipe
def  convert_to_string(num):
     return  'The Number: %s'  %  num
 
@Pipe
def  echo(item):
     print  item
     return  item
 
def  force(sqs):
     for  item  in  sqs:  pass
 
nums  =  [ 1 2 3 4 5 6 7 8 9 10 ]
 
force(nums | even_filter | multiply_by_three | convert_to_string | echo)

转载于:https://www.cnblogs.com/bonelee/p/11235955.html

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/djph26741/article/details/101520644

智能推荐

综述|线结构光中心提取算法研究_Tom Hardy的博客-程序员宅基地

点击上方“3D视觉工坊”,选择“星标”干货第一时间送达摘 要: 线结构光扫描是三维重建领域的关键技术。光条纹中心提取算法是决定线结构光三维重建精度以及光条纹轮廓定位准确性的重要因素。本文详..._曲线拟合模型提取中心线

Win10 文件夹下无法自动刷新的问题(终极版)_win10文件夹不自动刷新_coder_Alger的博客-程序员宅基地

问题其他近似描述:新建文件夹不显示,需要手动刷新显示; 删除文件夹依然存在,需要手动刷新消失; 保存文件不显示,需要手动刷新显示;解决方法:修改注册表 InstanceHKEY_CLASSES_ROOT\Wow6432Node\CLSID\{BDEADE7F-C265-11D0-BCED-00A0C90AB50F}\Instance 下创建一个 Dword 字段 DontRefresh ,并配置为 0注意:若没有对应字段,则新建即可。..._win10文件夹不自动刷新

golang:AES/ECB/PKCS5 加密解密 url-safe-base64_golang对消息进行解密,加密算法:aes-128 加密模式:ecb 填充方式:pkcs5_OceanStar的学习笔记的博客-程序员宅基地

因为项目的需要用到golang的一种特殊的加密解密算法AES/ECB/PKCS5,但是算法并没有包含在标准库中,经过多次失败的尝试,终于解码成功,特此分享:/*描述 : golang AES/ECB/PKCS5 加密解密date : 2016-04-08*/package mainimport ( "bytes" "crypto/aes" "crypt..._golang对消息进行解密,加密算法:aes-128 加密模式:ecb 填充方式:pkcs5

Unity Animator SetFloat()函数_会思考的猴子的博客-程序员宅基地

Animator. SetFloat(string name, float value);Parameters 参数name The name of the parameter. 该参数的名称。 value The new value for the parameter. 该参数的新值。 Description 描述Sets the value of ..._setfloat

菜鸟操作:QString和QMap转化(QMap嵌套QMap)_qt map 嵌套_从心开始 >的博客-程序员宅基地

将QMap中的数据全都放到QString中,包括符号,我这里使用大括号来代替原本的小括号(因为我太怀念python的字典了),用中文的双引号代替原本英文的双引号,这样就实现从QMap到QString的转换;从QString到QMap,其实主要是字符串的解析,难就难在要找到子字符串的起始下标和结束下标,这个简单推导一下就行了_qt map 嵌套

随便推点

【已解决】Tomcat 控制台中文乱码问题_哈利Hallie的博客-程序员宅基地

修改logging.properties文件中java.util.logging.ConsoleHandler.encoding = GBK

[Next] Next.js+Nest.js实现GitHub第三方登录_nestjs 第三方登录_qq836869520的博客-程序员宅基地

GitHub OAuth 第三方登录 第三方登录的关键知识点就是 OAuth2.0 . 第三方登录,实质就是 OAuth 授权 . OAuth 是一个开放标准,允许用户让第三方应用访问某一个网站的资源,而不需要提供账号和密码. 总体就是:myapp <===> user <===> github 授权的总体流程 用户进入到我的网站,我想要获取到用户的 GitHub ..._nestjs 第三方登录

VLD在VS2019中的使用以及应用程序无法正常启动(0xc0150002)_vld报错_okzuhedu的博客-程序员宅基地

Visual LeakDetector(VLD)是一款用于Visual C++的免费的内存泄露检测工具。但是在使用时可能会发生一些错误,可能是因为VLD的版本问题。有时候项目运行时会发生以下两个错误:1、运行提示,“无法启动此程序,因为计算机中丢失vld_x64.dll”2、运 行提示,“应用程序无法正常启动(0xc0150002)”今天再次使用发现启动一直报错,然后翻阅以前使用的案例发现有几个dll没有添加,原来是依赖项不全。以前没有发现这个问题是由于安装的vld,本次只是把inc_vld报错

桌面ui html,GitHub - Samotorcan/HtmlUi: Framework for creating desktop C# applications with HTML user ..._鲁严波的博客-程序员宅基地

HtmlUiHtmlUi is a framework for creating desktop C# applications with HTML user interface.OverviewThe framework uses CEF library to render the UI and C# to connect controllers with the UI. For client ..._cef 桌面ui

jenkins上github账号配置_jenkins添加git用户后,不显示_懒懒的小菜鸟的博客-程序员宅基地

进入manage jenkins-manage credentials,添加凭据,选择方式:username with passwordscope根据需要选择,username\password输入你的github的用户名及密码即可,这样在项目配置时就可以选择配置好的credentials:就可以持续集成你在github上的代码了。..._jenkins添加git用户后,不显示

运行rviz时出现[ERROR]: Could not load model、Cannot locate resource package错误_could not load pixmap 'package://rviz/icons/rotate-程序员宅基地

问题运行solidworks导出的urdf功能包下的display.launch,单独打开一个rviz去接收模型和tf数据时,出现如下错误:[ERROR] [1640699688.189865241]: Could not load model 'package://agv_model/meshes/base_link.STL' for link 'base_link': OGRE EXCEPTION(6:FileNotFoundException): Cannot locate resource p_could not load pixmap 'package://rviz/icons/rotate.svg' -- using default cur

推荐文章

热门文章

相关标签