パイプラインと関数の部分的な適用、なぜそれがPythonにあるのか



Pythonの主な利点の1つは、その表現力です。言語の機能により、データの変換を簡潔に記述することができます。私の意見では、Pythonには、データ変換をより便利に記述し、言語の機能コンポーネント、特に「関数パイプライン」とその部分的なアプリケーションを補足するのに役立つツールがいくつかありません。したがって、この投稿では、これらの資金の可能性と必要性​​について、それらを実装するための実験とともに水を注ぎます。私は多くの方法で批判を受けました。読書を楽しむ!



PythonのFPと、たとえばパイプラインが十分でない理由について簡単に説明します。



Pythonには、map()、reduce()、filter()、ラムダ関数、イテレーター、ジェネレーターなどの非常に便利な基本ツールがいくつかあります。この記事に不慣れな方はぜひお勧めします一般に、これにより、リストやタプルなどの変換をすばやく自然に記述することができます。非常に頻繁に(私と私の友人のpythonistsと一緒に)何が起こるか一発ギャグ-基本的に、一連の順次変換、フィルター、例:

Kata with CodeWars:Find



n[ab]n=0len((nn n -番号nのi番目のビット



, ( ), .



:



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]


" ". .





( "|" — ):



# 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 . , ( ):



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)


, , , kwargs, .



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))




, , , , , , , .




All Articles