Fluent Python Ch05
( 출처 : 전문가를 위한 파이썬 / Fluent Python )
[ First-Class Functions ]
1. Treating Function like OBJECT
def factorial(n):
'''returns n!'''
return 1 if n < 2 else n * factorial(n-1)
factorial.__doc__
#------------------------------------------------#
'returns n!'
help(factorial)
#------------------------------------------------#
Help on function factorial in module __main__:
factorial(n)
returns n!
map
함수의 인자로써, function을 넣을 수 있음
factorial(5),factorial(6),factorial(7)
list(map(factorial,[5,6,7]))
#----------------------------------------#
(120, 720, 5040)
[120, 720, 5040]
2. Higher-Order Functions
Higher-Order Functions
= function that takes a function as argument
fruits = ['strawberry', 'fig', 'apple', 'cherry', 'raspberry', 'banana']
def reverse(word):
return word[::-1]
fruits1 = sorted(fruits, key=len) # 인자로써 함수 사용
fruits2 = sorted(fruits)
fruits3 = sorted(fruits, key=reverse)
fruits1
# ['fig', 'apple', 'cherry', 'banana', 'raspberry', 'strawberry']
fruits2
# ['apple', 'banana', 'cherry', 'fig', 'raspberry', 'strawberry']
fruits3
# ['banana', 'apple', 'fig', 'raspberry', 'strawberry', 'cherry']
3. Map, Filter 대안
List Comprehension이 낫다! ( more readable )
list(map(my_function,range(100)))
[my_function(i) for i in range(100)]
4. Reduce
most common use case : summation
from functools import reduce
from operator import add
reduce(add, range(100))
sum(range(100))
5. Anonymous Functions
lambda
-
anonymous fuction
-
example
fruits = ['strawberry', 'fig', 'apple', 'cherry', 'raspberry', 'banana'] fruits2 = sorted(fruits, key=lambda word: word[::-1]) fruits2 # ['banana', 'apple', 'fig', 'raspberry', 'strawberry', 'cherry']
6. call
class myclass():
def __init__(self,x,y):
self.x=x
self.y=y
def __call__(self,z):
return (self.x+self.y)*z
C = myclass(10,20)
C.x # 10
C.y # 20
C(5) # 150 ( = (10+20)x5 )
7. From Positional to Keyword-Only Parameters
별 2개 : mappings ( ex. dictionary )
my_dict =dict({'a':1,'b':2})
def function1(**dicts):
print(dicts.keys())
function1(**my_dict)
#dict_keys(['a', 'b'])
별 1개 : iterables ( ex. list )
my_list = [1,2,3]
def function2(*list):
print(sum(list))
function2(*my_list)
# 6
8. Packages for Functional Programming
from functools import reduce
from operator import mul
Factorial 구현하기
-
방법 1) Reduce & lambda
def fact(n): return reduce(lambda a, b: a*b, range(1, n+1))
-
방법 2) Reduce & operator.mul
def fact(n): return reduce(mul, range(1, n+1))
itemgetter
metro_data = [
... ('Tokyo', 'JP', 36.933, (35.689722, 139.691667)),
... ('Delhi NCR', 'IN', 21.935, (28.613889, 77.208889)),
... ('Mexico City', 'MX', 20.142, (19.433333, -99.133333)),
... ('New York-Newark', 'US', 20.104, (40.808611, -74.020386)),
... ('Sao Paulo', 'BR', 19.649, (-23.547778, -46.635833)),
... ]
용도 1
from operator import itemgetter
# itemgetter(1) : 2번째 ( JP/IN/MX/US/BR )기분으로 sorting
for city in sorted(metro_data, key=itemgetter(1)):
print(city)
#----------------------------------------------------------#
('Sao Paulo', 'BR', 19.649, (-23.547778, -46.635833))
('Delhi NCR', 'IN', 21.935, (28.613889, 77.208889))
('Tokyo', 'JP', 36.933, (35.689722, 139.691667))
('Mexico City', 'MX', 20.142, (19.433333, -99.133333))
('New York-Newark', 'US', 20.104, (40.808611, -74.020386))
용도 2
cc_name = itemgetter(1, 0)
for city in metro_data:
print(cc_name(city))
#-----------------------------------------#
('JP', 'Tokyo')
('IN', 'Delhi NCR')
('MX', 'Mexico City')
('US', 'New York-Newark')
('BR', 'Sao Paulo')
9. NamedTuple
from collections import namedtuple
LatLong = namedtuple('LatLong', 'lat long')
Metropolis = namedtuple('Metropols', 'name cc pop coord')
metro_areas = [Metropolis(name, cc, pop, LatLong(lat, long))
for name, cc, pop, (lat, long)
in metro_data]
metro_areas[0]
#---------------------------------------------#
Metropolis(name='Tokyo', cc='JP', pop=36.933, coord=LatLong(lat=35.689722,
long=139.691667))
metro_areas[0].coord.lat
#---------------------------------------------#
35.689722
attrgetter
from operator import attrgetter
name_latitude = attrgetter('name', 'coord.lat')
for city in sorted(metro_areas, key=attrgetter('coord.lat')):
print(name_latitude(city))
#-----------------------------------------------------------#
('Sao Paulo', -23.547778)
('Mexico City', 19.433333)
('Delhi NCR', 28.613889)
('Tokyo', 35.689722)
('New York-Newark', 40.808611)