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)


Tags:

Categories:

Updated: