写点什么

2. Python 函数式编程中的字符串,元组,函数的分类,高阶函数,一篇文章都介绍一遍

发布于: 6 小时前

函数式编程中的字符串

在函数式编程中,经常用到 Python 字符串,因其是不可变数据结构。


字符串本身是一个对象,具备很多对象方法,与常识中函数的使用不太相同,例如下述代码


my_str = "xiangpica"print(my_str.upper())print(len(my_str.upper()))
复制代码


其中 len() 函数的用法被称为前置写法,而 my_str.upper() 被称为后置写法,这样很容易造成函数式编程的理解问题,所以需要系统性的解决该问题。


如果上述代码可以修改为 len(upper(my_str)),就变得相对容易理解。


# 类型 Text 是 str 的别名from typing import Textmy_str = "xiangpica"
def upper(str: Text) -> Text: return str.upper()
print(upper(my_str))print(len(upper(my_str)))
复制代码


上述代码重新定义了一个前置用法的函数 upper,用于解决函数式编程中的一致性问题,该解决办法在后续代码中会经常出现。

不变类型元组

除字符串外,Python 中的另一个不可变数据类型为元组,元组分为普通元组与命名元组。


普通元组的声明与访问


在之前的滚雪球系列中对元组的基本知识,已经进行了说明,可以去稍微复习一下,然后在进入本文的学习。


先看一下代码,然后再判断是否可以理解。


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 模块加入不会影响程序的运行不会报正式的错误,仅作为类型检查,防止运行时出现参数、返回值类型不符,开发人员查阅。


除上述内容外,还可以使用命名元组来实现。


from collections import  namedtuple
Language = namedtuple("Language",("name1", "name2", "name3"))
l = Language("c", "python", "js")print(l)print(l.name1)
复制代码


或者直接使用 typing 模块的 NamedTuple 也可以。


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() 对比学习

anyall 两个函数属于规约函数,进行的操作叫做布尔规约,即将一个集合的元素归约为 True 或者 False,all 需要所有值都是 True,any 只要有一个值是 True 即可。


lensum 也是归约函数,它们分别表示计算集合中所有值的个数和汇总值。

zip()、reversed()、enumerate()

zip 函数可以把多个可迭代对象或者序列,之间的数据进行交叉组合,即将 n 个元素的可迭代对象转换为 n 元组,然后返回一个生成器。


如果 zip 函数没有输入参数,那将返回一个空列表 []


a = zip()print(list(a))
复制代码


reversed 函数用于改变序列顺序,即反转序列。


enumerate 函数获取序列或者可迭代对象的下标值,转换成概念描述就是将可迭代对象映射为二元组序列(带上序号了),每个二元组序列中,第一个元素是下标值,第二个元素是值本身。

高阶函数

学习 Python 函数式编程,绕不开高阶函数的学习,高阶函数就是以函数为参数,或者以返回值为函数的函数。

函数 maxmin()

上述两个函数是规约函数,即输入的是集合,输出的是单个值,主要用途就是寻找极值。


一般在学习的时候,可以把二者当成普通的函数,也可用于高阶函数,主要为参数位置的差异。


最简单的用法为:


max_num = max(1, 2, 3, 4)min_num = min(1, 2, 3, 4)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)
# 第二种写法,比较字符串长度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 函数用于将一个集合映射到另一个集合,例如可以将一个由字符串组成的列表中的每一项,都转换为整数。


data = ["1", "2", "3"]print(map(int, data))print(list(map(int, data)))
复制代码


代码 map(int, data) 的含义就是将 int 函数作用于 data 中的每一项。


map 函数的第一个参数也可以用 lambda 代替。


data = ["1", "2", "3"]print(map(lambda x: int(x), data))print(list(map(int, data)))
复制代码

filter 函数

filter 函数主要用于将一个**判定函数(谓语函数)**用于集合的每一个元素,最后得到满足判定函数的结果集,测试代码如下:


data = [1, 3, 5, 7, 9]print(filter(lambda x: x > 3, data))print(list(filter(lambda x: x > 3, data)))
复制代码

sorted 函数

sorted 函数也支持高阶函数 key 参数定制规则。


result = sorted(["afghsss", "abc", "ceda", "aaaaa"], key=lambda x: len(x))print(result)
复制代码

同一需求的不同效率问题

通过 map 函数,生成器表达式,存在迭代器的生成器函数分别多 一亿 数据量的列表进行测试。


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-06demo1(demo, my_list) # 程序运行耗时 5.1070000000041915e-06cost_time = time.perf_counter() - start
print("程序运行耗时", cost_time)
复制代码


得到的结果是 map 最快,所以用就完事了。

写在后面

滚雪球学 Python 第四轮,非常理论的一个系列,跟上大部队的节奏,走起来,有任何问题,都可以在评论区留言,一般 1 小时之内都能解决。


今天是持续写作的第 <font color=red>215</font> / 365 天。可以<font color=#04a9f4>关注</font>,<font color=#04a9f4>点赞</font>、<font color=#04a9f4>评论</font>、<font color=#04a9f4>收藏</font>。


更多精彩


发布于: 6 小时前阅读数: 4
用户头像

爬虫 100 例作者,蓝桥签约作者,博客专家 2021.02.06 加入

6 年产品经理+教学经验,3 年互联网项目管理经验; 互联网资深爱好者; 沉迷各种技术无法自拔,导致年龄被困在 25 岁; CSDN 爬虫 100 例作者。 个人公众号“梦想橡皮擦”。

评论

发布
暂无评论
2. Python函数式编程中的字符串,元组,函数的分类,高阶函数,一篇文章都介绍一遍