>  기사  >  백엔드 개발  >  Python 함수형 프로그래밍, 이 기사를 읽어보세요!

Python 함수형 프로그래밍, 이 기사를 읽어보세요!

PHPz
PHPz앞으로
2023-04-18 19:22:011468검색

Python 함수형 프로그래밍, 이 기사를 읽어보세요!

이 글에서는 Python의 함수형 프로그래밍 기술을 간단하게 소개합니다.

Python 함수형 프로그래밍, 이 기사를 읽어보세요!

일급 함수

Python에서 함수는 "일급 시민"입니다. 즉, 함수는 int와 같은 다른 데이터 유형과 동등한 위치에 있습니다.

따라서 함수를 변수에 할당하고, 이를 다른 함수에 인수로 전달하고, 다른 데이터 구조(예: dicts)에 저장하고, 다른 함수의 반환 값으로 사용할 수 있습니다.

함수를 객체로 처리

다른 데이터 유형(예: 문자열, 목록 및 int)은 객체이므로 Python에서는 함수도 객체입니다. 자신의 이름을 출력하는 예제 함수 foo를 살펴보겠습니다.

def foo():
print("foo")

함수는 객체이므로 foo 함수를 임의의 변수에 할당한 다음 해당 변수를 호출할 수 있습니다. 예를 들어, bar 변수에 함수를 할당할 수 있습니다.

bar = foo
bar()
#will print "foo" to the console

bar = foo 명령문은 foo 함수가 참조하는 객체를 bar 변수에 할당합니다.

객체를 함수로 처리

객체가 호출 가능한 경우 객체()와 같은 함수와 동일합니다. 이는 __call__ 메서드를 통해 달성됩니다.

예제는 다음과 같습니다.

class Greeter:
def __init__(self, greeting):
 self.greeting = greeting
def __call__(self, name):
 return self.greeting + " " + name

Greeter 클래스의 개체를 구성할 때마다 인사말을 외칠 수 있는 새 이름인 새 개체를 생성합니다. 아래와 같이

morning = Greeter("good morning") #creates the callable object
morning("john") # calling the object
#prints "good morning john" to the console

우리가 아침 객체를 호출할 수 있는 이유는 클래스 정의에서 __call__ 메소드를 사용했기 때문입니다. 객체가 호출 가능한지 확인하기 위해 내장된 callable 함수를 사용합니다.

callable(morning) #true
callable(145) #false. int is not callable.

데이터 구조 내부의 함수

함수는 다른 객체와 마찬가지로 데이터 구조 내부에 저장될 수 있습니다. 예를 들어 int to func 사전을 만들 수 있습니다. 이는 int가 수행할 단계의 약어일 때 유용합니다.

# store in dictionary
mapping = {
0 : foo,
1 : bar
}
x = input() #get integer value from user
mapping[x]() #call the func returned by dictionary access

마찬가지로 함수는 다양한 다른 데이터 구조에 저장될 수 있습니다.

함수를 매개변수 및 반환값으로 사용

함수는 다른 함수의 매개변수 및 반환값으로 사용될 수도 있습니다. 함수를 입력 또는 반환 함수로 받아들이는 함수를 고차 함수라고 하며 함수형 프로그래밍의 중요한 부분입니다.

고차 함수에는 강력한 기능이 있습니다. "Eloquent JavaScript"에 설명된 대로:

  • "고차 함수를 사용하면 추상 값뿐만 아니라 작업도 추상화할 수 있습니다."

예를 살펴보겠습니다. 항목 목록을 반복하고 순서대로 인쇄한다고 가정해 보겠습니다. 우리는 쉽게 반복 함수를 만들 수 있습니다:

def iterate(list_of_items):
 for item in list_of_items:
 print(item)

멋져 보이지만 단지 1단계 추상화일 뿐입니다. 목록을 반복하면서 인쇄 이외의 다른 작업을 수행하려면 어떻게 해야 합니까?

이것은 고차 함수의 존재 의미입니다. 수행할 반복 목록과 각 항목에 적용할 함수가 iterate_custom 함수에 대한 입력인 iterate_custom 함수를 만들 수 있습니다.

def iterate_custom(list_of_items, custom_func):
for item in list_of_items:
 custom_func(item)

이는 사소해 보일 수 있지만 실제로는 매우 강력합니다.

코드의 재사용성을 높이기 위해 추상화 수준을 높였습니다. 이제 목록을 인쇄할 때 이 함수를 호출할 수 있을 뿐만 아니라 시퀀스 반복과 관련된 목록에 대한 임의의 작업을 수행할 수도 있습니다.

함수를 반환할 수도 있으므로 작업이 더욱 간단해집니다. dict에 함수를 저장하는 것처럼 함수를 제어문으로 사용하여 적절한 함수를 결정할 수도 있습니다. 예:

def add(x, y):
 return x + y
def sub(x, y):
 return x - y
def mult(x, y):
 return x * y
def calculator(opcode):
 if opcode == 1:
return add
 elif opcode == 2:
return sub
 else:
 return mult
my_calc = calculator(2) #my calc is a subtractor
my_calc(5, 4) #returns 5 - 4 = 1
my_calc = calculator(9) #my calc is now a multiplier
my_calc(5, 4) #returns 5 x 4 = 20.

중첩된 함수

함수는 다른 함수 안에 있을 수도 있습니다. 이는 "내부 함수"입니다. 내장 함수는 메인 함수를 지원하는 하위 모듈 역할을 하는 재사용 가능한 작은 함수인 도우미 함수를 만들 때 유용합니다.

문제에 특정 함수 정의(매개변수 유형 또는 순서)가 필요한 경우 도우미 함수를 사용할 수 있습니다. 이러한 비전통적인 접근 방식은 문제 해결을 훨씬 더 간단하게 만듭니다. 예를 들면 http://www-inst.eecs.berkeley.edu/~cs61a/sp12/lectures/lect4-2x3.pdf를 참조하세요.

매개변수 n이 하나만 있는 피보나치 함수 fib(n)을 정의하려고 하며 n번째 피보나치 수를 반환해야 한다고 가정해 보겠습니다.

이러한 함수를 정의하는 한 가지 가능한 방법은 도우미 함수를 사용하여 피보나치 수열의 처음 두 항을 추적하는 것입니다(피보나치 수는 처음 두 숫자의 합이므로).

def fib(n):
 def fib_helper(fk1, fk, k):
 if n == k:
return fk
 else:
return fib_helper(fk, fk1+fk, k+1)
 if n <= 1:
return n
 else:
return fib_helper(0, 1, 1)

이 계산을 함수 본문에서 함수 매개변수로 옮기는 것은 매우 강력합니다. 재귀적 방법에서 발생할 수 있는 중복 계산을 줄이기 때문입니다.

단일 표현식 함수(람다 표현식)

함수에 이름을 붙이기 전에 함수를 작성하려면 어떻게 해야 하나요? 짧은 한 줄 함수(예: 위 예의 foo 또는 mult 함수)를 작성하려면 어떻게 해야 합니까?

파이썬에서는 람다 키워드를 사용하여 이러한 함수를 정의할 수 있습니다. 예는 다음과 같습니다.

mult = lambda x, y: x * y
mult(1, 2) #returns 2

mult 함수는 기존 def 키워드를 사용하여 정의된 함수와 동일하게 동작합니다.

참고: 람다 함수는 한 줄이어야 하며 프로그래머가 작성한 반환 문을 포함할 수 없습니다.

事实上,它们通常具备隐式的返回语句(在上面的示例中,函数想表达 return x * y,不过我们省略了 lambda 函数中的显式返回语句)。

lambda 函数更加强大和精准,因为我们还可以构建匿名函数(即没有名称的函数):

(lambda x, y: x * y)(9, 10) #returns 90

当我们只需要一次性使用某函数时,这种方法非常方便。例如,当我们想填充字典时:

import collections
pre_fill = collections.defaultdict(lambda: (0, 0))
#all dictionary keys and values are set to 0

接下来我们来看 Map、Filter 和 Reduce,以更多地了解 lambda。

Map、Filter 和 Reduce

Map

map 函数基于指定过程(函数)将输入集转换为另一个集合。这类似于上文提到的 iterate_custom 函数。例如:

def multiply_by_four(x):
 return x * 4
scores = [3, 6, 8, 3, 5, 7]
modified_scores = list(map(multiply_by_four, scores))
#modified scores is now [12, 24, 32, 12, 20, 28]

在 Python 3 中,map 函数返回的 map 对象可被类型转换为 list,以方便使用。现在,我们无需显式地定义 multiply_by_four 函数,而是定义 lambda 表达式:

modified_scores = list(map(lambda x: 4 * x, scores))

当我们想对集合内的所有值执行某项操作时,map 函数很有用。

Filter

就像名称所显示的那样,filter 函数可以帮助筛除不想要的项。例如,我们想要去除 scores 中的奇数,那么我们可以使用 filter:

even_scores = list(filter(lambda x: True if (x % 2 == 0) else False, scores))
#even_scores = [6, 8]

由于提供给 filter 的函数是逐个决定是否接受每一个项的,因此该函数必须返回 bool 值,且该函数必须是一元函数(即只使用一个输入参数)。

Reduce

reduce 函数用于「总结」或「概述」数据集。例如,如果我们想要计算所有分数的总和,就可以使用 reduce:

sum_scores = reduce((lambda x, y: x + y), scores)
#sum_scores = 32

这要比写循环语句简单多了。注意:提供给 reduce 的函数需要两个参数:一个表示正在接受检查的项,另一个表示所用运算的累积结果。

本文是关于函数式编程的一篇入门文章,虽然尽量完备地介绍了相关的知识,但并不是那么深入。如想了解更多,大家可以阅读以下资源:

  • Best Practices for Using Functional Programming in Python:https://kite.com/blog/python/functional-programming/
  • Functional Programming Tutorials and Notes:https://www.hackerearth.com/zh/practice/python/functional-programming/functional-programming-1/tutorial/

위 내용은 Python 함수형 프로그래밍, 이 기사를 읽어보세요!의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 51cto.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제