Python的主要优点之一是它的表现力。该语言的功能使您可以简洁地描述数据转换。在我看来,Python缺少一些工具,这些工具将有助于更方便地描述数据转换并补充语言的功能组件,尤其是“功能管道”及其部分应用程序。因此,在这篇文章中,我将通过实验来研究这些资金的可能性和必要性。我以多种方式来批评。享受阅读!
简要介绍Python中的FP以及为什么没有足够的管道(例如)
Python有一些非常方便的基本工具,例如map(),reduce(),filter(),lambda函数,迭代器和生成器。我建议每个不熟悉这篇文章的人。通常,所有这些都使您可以快速自然地描述列表,元组等的转换。很多时候(和我以及我的朋友pythonists)会发生什么单线-本质上是一组顺序转换,过滤器,例如:
带有CodeWars的Kata:查找
任务很简单,不幸的是(幸运的是,对于这篇文章来说),没有比正面更好的解决方案了。
我的决定:
def sum_dig_pow(a, b): # range(a, b + 1) will be studied by the function
powered_sum = lambda x: sum([v**(i+1) for i,v in enumerate(map(lambda x: int(x), list(str(x))))])
return [i for i in range(a,b+1) if powered_sum(i)==i]
照原样使用FP的方法,我们会“从内而外”得到一个括号地狱。管道可以解决该问题。
功能管道
sim是我的意思,在理想情况下(“ |”运算符是个人喜好):
# f3(f2(f1(x)))
f1 | f2 | f3 >> x
pipeline = f1 | f2 | f3
pipeline(x)
pipeline2 = f4 | f5
pipeline3 = pipeline | pipeline2 | f6
...
然后powered_sum可以变成(代码不起作用):
powered_sum = str | list | map(lambda x: int(x), *args) | enumerate | [v**(i+1) for i,v in *args] | sum
对我来说,这段代码更容易编写和阅读。args一般看起来很陌生。实际上,事实证明,这样做(没有任何理想)不会爬进python的胆量:
from copy import deepcopy
class CreatePipeline:
def __init__(self, data=None):
self.stack = []
if data is not None:
self.args = data
def __or__(self, f):
new = deepcopy(self)
new.stack.append(f)
return new
def __rshift__(self, v):
new = deepcopy(self)
new.args = v
return new
def call_logic(self, *args):
for f in self.stack:
if type(args) is tuple:
args = f(*args)
else:
args = f(args)
return args
def __call__(self, *args):
if 'args' in self.__dict__:
return self.call_logic(self.args)
else:
return self.call_logic(*args)
自然,这是一个很大的拐杖,即使没有杂物也很有趣,尽管在类似情况下它并不那么重要。
pipe = CreatePipeline()
powered_sum = pipe | str | list | (lambda l: map(lambda x: int(x), l)) | enumerate | (lambda e: [v**(i+1) for i,v in e]) | sum
, , , , , .
( ):
def f_partitial (x,y,z):
return x+y+z
v = f_partial(1,2)
# type(v) = - f_partial, : ['z']
print(v(3))
#
print(f_partial(1,2,3))
( ). pipe :
powered_sum = pipe | str | list | map(lambda x: int(x)) | enumerate | (lambda e: [v**(i+1) for i,v in e]) | sum
# map
# map(lambda x: int(x))()
map(lambda x: int(x)) .
:
from inspect import getfullargspec
from copy import deepcopy
class CreatePartFunction:
def __init__(self, f):
self.f = f
self.values = []
def __call__(self, *args):
args_f = getfullargspec(self.f)[0]
if len(args) + len(self.values) < len(args_f):
new = deepcopy(self)
new.values = new.values + list(args)
return new
elif len(self.values) + len(args) == len(args_f):
return self.f(*tuple(self.values + list(args)))
:
# inspect map
m = lambda f, l: map(f, l)
#
pmap = CreatePartFunction(m)
powered_sum = pipe | str | list | pmap(lambda x: int(x)) | enumerate | (lambda e: [v**(i+1) for i,v in e]) | sum
( ), , , , :
def f (x,y,z):
return x+y+z
f = CreatePartFunction(f)
#
print(f(1,2,3))
#
print(f(1,2)(3))
print(f(1)(2,3))
#
# 2(3) - int callable
print(f(1)(2)(3))
#
print((f(1)(2))(3))
, , , , , , , .