30天Python学习计划👨💻 - 第11天 - 函数式编程基础
由 Mux 主办的 DEV 全球展示挑战赛:展示你的项目!
面向对象编程和函数式编程都遵循相同的原则——关注点分离。面向对象编程通过将属性及其操作组合在一个对象中来实现关注点分离class,而函数式编程则将属性及其操作分离,并使用函数来对对象执行操作。
今天,我探索了函数式编程概念在 Python 中的应用,并研究了如何运用函数式编程技术来组织 Python 代码。
在开发者圈子里,关于哪种编程范式更好的争论一直存在。许多人对编写纯面向对象代码或纯函数式代码持有强烈的观点。更务实的做法是了解两种范式的优势和局限性,并在必要时取长补短,取长补短。
以下是一些函数式编程的重要概念及其在 Python 中的实现。
纯函数
纯函数是函数式编程的核心和灵魂,就像类和对象是面向对象编程的核心和灵魂一样。
纯函数是指符合以下两个规则的函数:
- 如果输入相同内容,则始终返回相同输出。
- 它不会产生任何副作用。
副作用通常是指在函数范围之外更改数据,例如向控制台打印、进行网络请求、更改数据库、访问全局变量等。
def doubler(num):
'''
Accepts a number and multiplies it by 2
'''
return num * 2
print(doubler(5))
def emoji_appender(list, emoji):
'''
Accepts a list and a emoji and
appends to every item of list
'''
new_list = []
for item in list:
new_list.append(str(item) + emoji)
return new_list
print(emoji_appender([1,2,3], '😀')) # ['1😀', '2😀', '3😀']
print(emoji_appender(['alpha','beta','gamma'], '😀'))
# ['alpha😀', 'beta😀', 'gamma😀']
纯函数有哪些优点?
理想情况下,纯函数应该只执行一个特定的操作。由于纯函数在给定相同输入的情况下总是返回相同的输出,因此它们具有可预测性,非常容易测试。这种可预测性使得多个纯函数可以并行运行,因为它们没有副作用。这使得代码更易于阅读和理解。
一些重要的内置功能
Python 内置了一些函数,允许以函数式编程风格或声明式编程风格编写代码。这些函数是纯函数,不会修改输入数据,也不会产生任何副作用。
- 地图()
map该函数接受两个参数:第一个参数是一个执行某种操作的函数,第二个参数是一个可迭代对象。它会遍历可迭代对象中的每个元素,并应用传入的函数。
numbers = [1,2,3,4,5]
def multiply_by5(num):
return num * 5
result = map(multiply_by5, numbers)
print(result) # <map object at 0x7f572dcb7730> (Memory location of the map object)
print(list(result)) # [5, 10, 15, 20, 25] (to get the updated list)
print(numbers) # [1,2,3,4,5] (Unmodified)`
map该函数返回对象内存地址的引用map。要获取结果数据,需要将其作为参数传递给列表函数。需要注意的map是,该函数的输入和输出长度相同,并且map不会修改输入的可迭代对象。
- 筛选()
filter顾名思义,它会根据传入的函数过滤输入的可迭代数据。
color_to_remove = 'red'
colors = ['blue', 'green', 'black', 'red']
def remove_color(color):
return color != color_to_remove
result = filter(remove_color, colors)
print(list(result)) # ['blue', 'green', 'black']
print(colors) # ['blue', 'green', 'black', 'red'] (Unmodified)
就像之前一样map,filter该函数返回内存中存储过滤器对象的地址引用,要获取实际结果,需要将其传递给列表函数。输出长度可能等于或小于输入长度,具体取决于条件。filter此外,该函数不会更改或修改输入数据。
- 拉链()
内置zip函数接受多个可迭代对象,并将它们分组或压缩成元组。当不同的用户数据存储在数据库的不同列中,并且需要根据它们之间的关系将它们组合在一起时,这种功能非常有用。
emails = ['alan@gmail.com', 'ross@gmail.com']
usernames = ['alan', 'ross']
users = list(zip(emails,usernames))
print(users) # [('alan@gmail.com', 'alan'), ('ross@gmail.com', 'ross')]
print(emails) # ['alan@gmail.com', 'ross@gmail.com'] (Unmodified)
print(usernames) # ['alan', 'ross']
- 减少()
reduce它与上面提到的其他函数略有不同。reduce它不是 Python 内置函数的一部分,而是随 Python 解释器和软件包一起下载的某个包或工具包的一部分。因此,它需要从functools模块中导入。稍后会详细介绍模块。
reduce这有点难以理解。不过,借鉴 JavaScript 的方法,它array也reduce能实现同样的功能。它会在累加器中跟踪结果值。
reduce接受一个函数和一个可迭代对象作为必需参数,以及一个可选的初始化器,默认值为 0。
reduce可以将其视为将可迭代值减少或合并为单个值的方法。
from functools import reduce
numbers = [1,2,3,4]
def accumulator(acc, curr):
return acc + curr
sum = reduce(accumulator, numbers, 0)
print(sum) # 10
今天就到这里。核心概念已经基本讲解完毕,我相信函数式编程的概念会在Python更高级的章节中再次出现。明天我想再讲解一些剩余的函数式编程术语,并以清晰易懂的方式分享给大家。随着我不断解锁新的概念,探索Python的新领域,我越来越兴奋。希望你们也和我一样充满热情,并有兴趣继续学习。
祝你一切顺利!
文章来源:https://dev.to/arindamdawn/30-days-of-python-day-11-function-programming-i-4d9o