Chr*_*rno 1 python functional-programming
我正在编写一些 python 代码,并且正在实现一种我已经用多种语言反复完成的模式。我一直认为这是某种功能范例,并且可以在功能上实现(不使用循环for),但我没有看到它。Map获取一个系列并返回一个新系列。Reduce获取一系列结果并将其简化为单个结果。这两者都不是。
下面这个函数的想法是对单个字符串重复应用转换。在这种情况下:
def to_template(message):
mappers = [
('[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}', '{.uuid}'),
(' [0-9]{5,9}.', ' {.request_id}.')
]
result = message
for pattern, replacement in mappers:
result = re.sub(pattern, replacement, result)
return result
Run Code Online (Sandbox Code Playgroud)
问题:
在函数式编程术语中,这是折叠:您将替换操作列表折叠(即减少)为单个字符串,并以字符串作为起点。
在 Python 中,您可以使用模块reduce中的函数来编写此代码functools。
from functools import reduce
def to_template(message):
mappers = [ ... ]
return reduce(lambda r, p: re.sub(*p, r), mappers, message)
Run Code Online (Sandbox Code Playgroud)
reducere.sub使用 from 的元素mappers作为第一个参数并使用上一次调用的结果作为第二个参数重复调用。(第一次调用用作message的“第 0 个”返回值re.sub。)
递归地,可以实现reduce为
def reduce(f, itr, init):
if not itr:
return init
else:
return reduce(f, itr[1:], f(init, itr[0]))
Run Code Online (Sandbox Code Playgroud)
迭代地,它看起来很像你的函数:
def reduce(f, itr, init):
result = init
for x in itr:
result = f(result, x)
return result
Run Code Online (Sandbox Code Playgroud)
从理论上讲,您还可以想象使用函数组合将函数列表折叠成单个函数,然后应用于您的消息。
from functools import reduce, partial
def to_template(message):
mappers = [
partial(re.sub, '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}', '{.uuid}'),
partial(re.sub, ' [0-9]{5,9}.', ' {.request_id}.')
]
# Apply f first, so that reduce applies functions
# in the order they appear in the list.
def compose(f, g):
return lambda x: g(f(x))
def identity(x):
return x
f = reduce(compose, mappers, identity)
return f(message)
Run Code Online (Sandbox Code Playgroud)
但是,对于大量映射操作,您可能会通过reduce和compose构建的嵌套函数调用达到递归限制。
| 归档时间: |
|
| 查看次数: |
57 次 |
| 最近记录: |