
Salah satu keunggulan utama Python adalah ekspresifnya. Fungsionalitas bahasa memungkinkan Anda mendeskripsikan transformasi data secara ringkas. Menurut pendapat saya, Python kekurangan beberapa alat yang akan membantu mendeskripsikan transformasi data dengan lebih mudah dan melengkapi komponen fungsional bahasa, khususnya, "pipa fungsi" dan aplikasi parsial mereka. Oleh karena itu, dalam posting ini saya menuangkan air pada kemungkinan dan kebutuhan dana ini dengan eksperimen untuk implementasinya. Saya datang dengan berbagai cara untuk mengkritik. Selamat membaca!
Secara singkat tentang FP di Python dan mengapa tidak ada cukup pipeline misalnya
Python memiliki beberapa alat dasar yang cukup berguna seperti map (), reduce (), filter (), fungsi lambda, iterator, dan generator. Saya menyarankan semua orang yang tidak terbiasa dengan artikel ini . Secara umum, semuanya memungkinkan Anda dengan cepat dan alami mendeskripsikan transformasi atas daftar, tupel, dan sebagainya. Sangat sering (dengan saya dan teman saya pythonist) apa yang terjadisatu baris- dasarnya satu set transformasi sekuensial, filter, misalnya:
Kata dengan CodeWars : Temukan
Tugasnya cukup sederhana, sayangnya (tetapi untungnya untuk posting ini), tidak ada solusi yang lebih baik daripada langsung.
Keputusanku:
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]
Dengan menggunakan sarana FP sebagaimana adanya, kita mendapatkan tanda kurung neraka "dari dalam ke luar". Pipa bisa memperbaikinya.
Saluran pipa fungsi
Yang saya maksud dengan sim dalam kasus ideal (operator "|" adalah preferensi pribadi):
# 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))
, , , , , , , .