首页 > 技术文章 > 函数与函数式编程(生成器 && 列表解析 && map函数 && filter函数)-(四)

wendyw 2019-10-29 09:05 原文

在学习python的过程中,无意中看到了函数式编程。在了解的过程中,明白了函数与函数式的区别,函数式编程的几种方式。

函数定义:函数是逻辑结构化和过程化的一种编程方法。

过程定义:过程就是简单特殊没有返回值的函数。

函数式编程定义:先定义一个数学函数,然后按照这个数学模型用编程语言去实现它。

  1. 函数式编程实现的目的:可以使程序员写出更为精确和高效的代码。

  2. 函数式编程的优势:在以函数式风格写代码时,函数应该设计成没有其他副作用。函数接收参数并生成输出而不保留任何状态或修改任何不反映在返回值中的值。这种理想方式的函数可以被当成纯函数式函数。

#非纯函数:
def test1(mylist):
  mylist.pop(-1)
#纯函数:
def test2(mylist):
  return mylist[:-1]
Python中函数定义方法:
def test(x):  #def 定义函数的关键字,test是函数名,()内可定义形参
       “the function definitions”#文档描述
       x+=1                        #泛指代码块或程序处理逻辑
       Return x          #定义返回值

函数优势:

1、代码可重用

2、保持一致性

3、可扩展性

了解函数式编程,需要了解几种方式:生成器、列表解析、函数式等内容。

1.生成器

生成器:生成器(generator)是对象,在每次调用它的next()方法时返回一个值,直到它抛出StopIteration。

操作:创建一个生成器,只需要写一个普通的包含yield语句的python函数。

原理:python检测对yield的使用并将这个函数标识为一个生成器,当函数执行到yield语句时,它会像return语句那样返回一个值。

与return的区别:生成器会保存对栈的引用,它将被用来在下一次调用next函数时恢复函数的执行。

PS:当一个函数或过程没有返回值的时候,python解释器会默认返回为None.

2.列表解析

列表解析(list comprehension,简称listcomp):可以通过声明在单行内构造列表的内容。

没有列表解析的情况:
>>>x=[]
>>>for i in (1,2,3)
... x.append(i)
...
>>>x
[1,2,3]
使用列表解析的实现
>>>x=[i for i in (1,2,3)]
>>>x
[1,2,3]
可以同时使用多条for语句并使用if语句过滤元素:
x=[word.capitalize()
for line in ("hello world?","world","or not")
for word in line.split()
If not word.startswith("or")
]
>>>x
["hello","world?","world!","Not"]

列表解析的目的:快速定义列表的简洁方式。

#构建字典和集合:
>>>{x:x.upper() for x in ["hello","world"]}
{"world":"WORLD","hello":"HELLO"}
>>>{x.upper() for x in ["hello","world"]}
set(["WORLD","HELLO"])

3 函数式编程函数-内置函数

python包括很多针对函数式编程的工具,比如map()、filter()、sort()函数等内置函数。

3.1 map()函数

  python3 返回可迭代的map对象.map(function,iterable)对iterable中的每一个元素应用function,并在python3中返回可迭代的map对象。

#map(function,iterable)返回可迭代的map对象 
>>>map(lambda x:x+"bzz!",["I think","I'm good"])
<map object at 0x7fe7101abdd0> 
>>>list(map(lambda x:x+"bzz!",["I think","I'm good"]))
[I thinkbzz,I’m goodbzz]

 3.2 filter()函数

filter(function or None,iterable)对iterable中的元素应用function对返回结果进行过滤,并在python3中返回可迭代的filter对象。

#Filter(function or None,iterable)对iterable中的元素应用function对返回结果进行过滤,并再python3中返回可迭代的filter对象。
>>>filter(lambda x:x.startswith("I"),["I think","I'm good"])
<filter object at 0x000001884247BB88>
>>>list(filter(lambda x:x.startswith("I "),["I think","I'm good"]))
['I think']
#PS:生成器和列表解析实现与filter或者map等价的函数

使用列表解析实现map

#使用列表解析实现map
>>>(x +"bzz!" for x in ["I think","I’m good"])
<generator object <genexpr> at 0x7f9a0d697dc0>
>>>[x +"bzz!" for x in ["I think","I’m good"]]
["I thinkbzz","I’m goodbzz"]

使用列表解析实现filter

#使用列表解析实现filter
>>>(x for x in ["I think","I’m good"] if x.startswith("I"))
<generator object <genexpr> at 0x7f9a0d697dc0>
>>>[x for x in ["I think","I’m good"] if x.startswith("I")]
["I think"]

3.3 enumerate()函数

enumerate(iterable[,start])返回一个可迭代的enumerate对象,它生产一个元组序列,每个元组包括一个整型索引和iterable中对应的元素。

#enumerate(iterable[,start])返回一个可迭代对象,生成一个元组序列,对应索引(从start开始)和iterable中对应的函数
for i,item in enumerate(mylist):
    print("Item %d: %s" %(i, item))

3.4 sorted()函数

sorted(iterable,cmp=None,key=None,reverse=False)函数对所有可迭代的对象进行排序操作

#sorted(iterable,cmp=None,key=None,reverse=False)返回iterable的一个已排序版本,通过key可以提供一个返回要排序的值的函数
>>>a = [5,7,6,3,4,1,2]
>>> b = sorted(a)       # 保留原列表
>>> a 
[5, 7, 6, 3, 4, 1, 2]
>>> b
[1, 2, 3, 4, 5, 6, 7]
 
>>> L=[('b',2),('a',1),('c',3),('d',4)]
>>> sorted(L, cmp=lambda x,y:cmp(x[1],y[1]))   # 利用cmp函数
[('a', 1), ('b', 2), ('c', 3), ('d', 4)]
>>> sorted(L, key=lambda x:x[1])               # 利用key
[('a', 1), ('b', 2), ('c', 3), ('d', 4)]
 
 
>>> students = [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]
>>> sorted(students, key=lambda s: s[2])            # 按年龄排序
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
 
>>> sorted(students, key=lambda s: s[2], reverse=True)       # 按降序
[('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]
>>>

3.5 zip()函数

zip(iter1[,iter2[...]])函数接收多个序列并将他们组合成元组。它在将一组键和一组值组合成字典。

>>>keys=["foobar","barzz","ba!"]
>>>map(len,keys)
<map object at 0x00000188422B3408>
>>>zip(keys,map(len,keys)) #接收keys与keys的长度合成元组
<zip object at 0x0000018842225448>
>>>list(zip(keys,map(len,keys))) #生成列表
[('foobar', 6), ('barzz', 5), ('ba!', 3)]
>>>dict(zip(keys,map(len,keys))) #生成字典
{'foobar': 6, 'barzz': 5, 'ba!': 3} 

推荐阅读