函数式编程中的字符串
在函数式编程中,经常用到 Python 字符串,因其是不可变数据结构。
字符串本身是一个对象,具备很多对象方法,与常识中函数的使用不太相同,例如下述代码
1
2
3
|
my_str = "xiangpica" print (my_str.upper()) print ( len (my_str.upper())) |
其中 len()
函数的用法被称为前置写法,而 my_str.upper()
被称为后置写法,这样很容易造成函数式编程的理解问题,所以需要系统性的解决该问题。
如果上述代码可以修改为 len(upper(my_str))
,就变得相对容易理解。
1
2
3
4
5
6
7
|
# 类型 Text 是 str 的别名 from typing import Text my_str = "xiangpica" def upper( str : Text) - > Text: return str .upper() print (upper(my_str)) print ( len (upper(my_str))) |
上述代码重新定义了一个前置用法的函数 upper
,用于解决函数式编程中的一致性问题,该解决办法在后续代码中会经常出现。
不变类型元组
除字符串外,Python 中的另一个不可变数据类型为元组,元组分为普通元组与命名元组。
普通元组的声明与访问
在之前的文章中对元组的基本知识,已经进行了说明,可以去稍微复习一下,然后在进入本文的学习。
先看一下代码,然后再判断是否可以理解。
1
2
3
4
5
6
|
from typing import Tuple , Text, Callable LANGUAGE = Tuple [Text, Text, Text] python: Callable [[LANGUAGE], Text] = lambda languages: languages[ 1 ] items = ( "c" , "python" , "js" ) a = python(items) print (a) |
上述代码定义了一个新的类型 LANGUAGE
,该类型是一个元组,具备三个元素。
python
类型注解是 Callable[[LANGUAGE], Text]
,即它的参数是 LANGUAGE
类型,返回值是字符串类型。
注意 typing
模块加入不会影响程序的运行不会报正式的错误,仅作为类型检查,防止运行时出现参数、返回值类型不符,开发人员查阅。
除上述内容外,还可以使用命名元组来实现。
1
2
3
4
5
|
from collections import namedtuple Language = namedtuple( "Language" ,( "name1" , "name2" , "name3" )) l = Language( "c" , "python" , "js" ) print (l) print (l.name1) |
或者直接使用 typing
模块的 NamedTuple
也可以。
1
2
3
4
5
6
7
8
|
from typing import NamedTuple, Text class Language(NamedTuple): name: Text description: Text l = Language( "C" , "C语言" ) print (l) print (l.name) print (l.description) |
函数式的分类
函数大类分为两种:
- 标量函数:函数的返回结果为一个值;
- 集合函数:函数的结果为可迭代的集合。
集合函数也可以细分:
- 规约/累积函数:将集合内的元素进行累积计算,最后得到一个值;
- 映射函数:将标量函数应用于几个的每个元素,最后得到一个与原集合相同长度的新集合;
- 过滤函数:将标量函数应用于每个元素,保留一部分,得到一个子集。
有了上述概念之后,对于函数式编程的理解可以更进一步。
any() 、all() 、len()、sum() 对比学习
any
与 all
两个函数属于规约函数,进行的操作叫做布尔规约,即将一个集合的元素归约为 True 或者 False,all
需要所有值都是 True,any
只要有一个值是 True 即可。
len
与 sum
也是归约函数,它们分别表示计算集合中所有值的个数和汇总值。
zip()、reversed()、enumerate()
zip
函数可以把多个可迭代对象或者序列,之间的数据进行交叉组合,即将 n 个元素的可迭代对象转换为 n 元组,然后返回一个生成器。
如果 zip
函数没有输入参数,那将返回一个空列表 []
。
1
2
|
a = zip () print ( list (a)) |
reversed
函数用于改变序列顺序,即反转序列。
enumerate
函数获取序列或者可迭代对象的下标值,转换成概念描述就是将可迭代对象映射为二元组序列(带上序号了),每个二元组序列中,第一个元素是下标值,第二个元素是值本身。
高阶函数
学习 Python 函数式编程,绕不开高阶函数的学习,高阶函数就是以函数为参数,或者以返回值为函数的函数。
函数 max 和 min()
上述两个函数是规约函数,即输入的是集合,输出的是单个值,主要用途就是寻找极值。
一般在学习的时候,可以把二者当成普通的函数,也可用于高阶函数,主要为参数位置的差异。
最简单的用法为:
1
2
3
4
|
max_num = max ( 1 , 2 , 3 , 4 ) min_num = min ( 1 , 2 , 3 , 4 ) print (max_num) print (min_num) |
接下来就是其高阶函数模式的实现,自定义比较规则。
1
2
3
4
5
6
7
8
9
10
|
# 第一种写法,比较字符串长度 max_num = max ( "a" , "abc" , "ceda" , "aaaaa" , key = lambda x: len (x)) min_num = min ( "a" , "abc" , "ceda" , "aaaaa" , key = lambda x: len (x)) print (max_num) print (min_num) # 第二种写法,比较字符串长度 max_num = max ([ "a" , "abc" , "ceda" , "aaaaa" ], key = lambda x: len (x)) min_num = min ([ "a" , "abc" , "ceda" , "aaaaa" ], key = lambda x: len (x)) print (max_num) print (min_num) |
上述代码的 key
为可选参数,默认值为 None。
map 函数
map
函数用于将一个集合映射到另一个集合,例如可以将一个由字符串组成的列表中的每一项,都转换为整数。
1
2
3
|
data = [ "1" , "2" , "3" ] print ( map ( int , data)) print ( list ( map ( int , data))) |
代码 map(int, data)
的含义就是将 int
函数作用于 data
中的每一项。
map
函数的第一个参数也可以用 lambda
代替。
1
2
3
|
data = [ "1" , "2" , "3" ] print ( map ( lambda x: int (x), data)) print ( list ( map ( int , data))) |
filter 函数
filter
函数主要用于将一个**判定函数(谓语函数)**用于集合的每一个元素,最后得到满足判定函数的结果集,测试代码如下:
1
2
3
|
data = [ 1 , 3 , 5 , 7 , 9 ] print ( filter ( lambda x: x > 3 , data)) print ( list ( filter ( lambda x: x > 3 , data))) |
sorted 函数
sorted
函数也支持高阶函数 key
参数定制规则。
1
2
|
result = sorted ([ "afghsss" , "abc" , "ceda" , "aaaaa" ], key = lambda x: len (x)) print (result) |
同一需求的不同效率问题
通过 map
函数,生成器表达式,存在迭代器的生成器函数分别多 一亿 数据量的列表进行测试。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
import time def demo(x): return x * 2 def demo1(f, l): for x in l: yield f(x) my_list = list ( range ( 1 , 10000000 )) start = time.perf_counter() # map(lambda x: x * 2, my_list) # 程序运行耗时 3.904999999998493e-06 # (demo(x) for x in my_list) # 程序运行耗时 6.310000000009364e-06 demo1(demo, my_list) # 程序运行耗时 5.1070000000041915e-06 cost_time = time.perf_counter() - start print ( "程序运行耗时" , cost_time) |
得到的结果是 map
最快,所以用就完事了。
以上就是简析Python函数式编程字符串和元组及函数分类与高阶函数的详细内容,更多关于Python函数式编程的资料请关注服务器之家其它相关文章!
原文链接:https://dream.blog.csdn.net/article/details/120153197