# Anonymous function and Lambda Expression
# def func(args):
# return ret_val
#
# func = landa arg: ret_val
def f(x):
return x - 1
print(f(3))
print(type(f))
ld_f = lambda x: x - 1
print(ld_f(3))
print(type(ld_f))
def last_char(s):
return s[-1]
print(last_char('hello'))
ld_f2 = lambda s: s[-1]
print(ld_f2('hello'))
# 결과
2
<class 'function'>
2
<class 'function'>
o
o
### 람다 사용
"""
1. 아규먼트는 제한 없이 사용 가능, 단 평가식은 한 개만
2. 함수 객체가 쓰이는 곳이면 대용 가능 (람다는 함수 객체를 반환)
"""
def main():
IsEvenOrOdd = \
lambda n : "Even number" if n % 2 == 0 else "Odd number"
print(IsEvenOrOdd(19))
print(IsEvenOrOdd(20))
if __name__ == '__main__':
main()
#결과
Odd number
Even number
### 람다 평가식의 활용
def main():
choice_nums = \
lambda s : ''.join([n for n in s if n.isdigit()])
print(choice_nums('apple101'))
print('\t')
find_sum = \
lambda s : sum([int(n) for n in str(s)])
print(find_sum('101'))
if __name__ == '__main__':
main()
#결과
101
2
### 함수에 람다 사용
def main():
l = ['1', '2', '9', '0', '-1', '-2']
print('Sorted numerically:', sorted(l, key=lambda n : int(n)))
print('Filtered positive even numbers:', \
list(filter(lambda n : (int(n) % 2 == 0 and int(n) > 0), l)))
print('Operation on each item using lambda and map:', \
list(map(lambda s : str(int(s) + 1), l)))
if __name__ == '__main__':
main()
#결과
Sorted numerically: ['-2', '-1', '0', '1', '2', '9']
Filtered positive even numbers: ['2']
Operation on each item using lambda and map: ['2', '3', '10', '1', '0', '-1']
# A map is a function.
# It takes a sequence as its second input and (==> nums)
# it takes a function as its first input. (==> lambda)
# 첫 번째 인자가 함수명 전달인데,
# 다른 함수를 부르는 대신 람다 함수를 생성해 던졌다.
nums = [2, 5, 9]
ret = map((lambda x : x*2), nums)
print(list(ret))
# 결과
[4, 10, 18]
# Use map to produce a new list called abbrevs_upper that contains all the same
# strings in upper case.
#
# abbrevs_upper = map(<transformer, abbrevs)
# The transformer is the hard part.
# Remember that the transformer has to be a function
# that function has to take one string as input
# and return the capitalization version of that string.
abbrevs = ["usa", "esp", "chn", "jpn", "mex", "can", "rus", "rsa", "jam"]
abbrevs_upper = map((lambda n : n.upper()), abbrevs)
print(list(abbrevs_upper))
# or
def transformer(st):
return st.upper()
abbrevs_upper2 = map(transformer, abbrevs)
print(list(abbrevs_upper2))
# 결과
['USA', 'ESP', 'CHN', 'JPN', 'MEX', 'CAN', 'RUS', 'RSA', 'JAM']
['USA', 'ESP', 'CHN', 'JPN', 'MEX', 'CAN', 'RUS', 'RSA', 'JAM']
### map의 사용예 (지정된 함수로 시퀀스 객체를 처리)
def main():
nums = 5
even_result = list(map(mymod, range(nums)))
ds = dict(zip(range(nums), even_result))
print('Is even? =>', ds)
pass
def mymod(n):
if n % 2 == 0:
return True
else:
return False
if __name__ == '__main__':
main()
# 결과
Is even? => {0: True, 1: False, 2: True, 3: False, 4: True}
### 리스스의 star 개수를 읽어 index, len(star) dict 생성
import random
max_star_len = 10
def main():
ls = []
d = {}
for i in range(10):
ls.append('*' * random.randint(0, max_star_len))
### for - enum을 통한 첨자 할당
for i, l in enumerate(ls):
d[i] = len(ls[i])
print(ls)
print(d)
print('\t')
### map, zip을 통한 묶음 dict 생성
l = list(map(len, ls))
d = dict(zip(range(max_star_len), l))
print(ls)
print(d)
if __name__ == '__main__':
main()
#결과
['**********', '**********', '', '*********', '***', '********', '***', '****', '*******', '*']
{0: 10, 1: 10, 2: 0, 3: 9, 4: 3, 5: 8, 6: 3, 7: 4, 8: 7, 9: 1}
['**********', '**********', '', '*********', '***', '********', '***', '****', '*******', '*']
{0: 10, 1: 10, 2: 0, 3: 9, 4: 3, 5: 8, 6: 3, 7: 4, 8: 7, 9: 1}
### map 클래스에 원하는 객체 타입을 지정해 변환
def main():
m = map(str, [1, 2, 3])
ls = list(m)
print(ls)
print(type(ls[0]))
print('\t')
s = map(int, ['1', '2', '3'])
li = list(s)
print(li)
print(type(li[0]))
if __name__ == '__main__':
main()
#결과
['1', '2', '3']
<class 'str'>
[1, 2, 3]
<class 'int'>
# 클래스에 range 객체도 던질 수 있다.
m = map(str, range(1, 11))
s = ''.join(m)
print(type(s), "s: {}".format(s))
# 결과
<class 'str'> s: 12345678910
# map, lambda 혼용
ls = list(range(1, 6))
lm = map(lambda x: x+1, map(int, ls))
print(list(lm))
# 결과
[2, 3, 4, 5, 6]
### list comprehension과 zip의 사용
### 두 개의 쌍 중에서 더 큰 값을 리턴
def main():
lx = [5, 2, 3]
ly = [1, 2, 4]
ls = [max(x, y) for x, y in zip(lx, ly)]
print(ls)
if __name__ == '__main__':
main()
#결과
[5, 2, 4]
### 람다를 이용 짝 중 큰수를 리턴
def main():
a = [5, 2, 3]
b = [1, 2, 4]
r = map(lambda pair : max(pair), zip(a, b))
print(list(r))
if __name__ == '__main__':
main()
#결과
[5, 2, 4]
### 람다, max 함수를 이용해 두 개의 쌍 중에서 더 큰 값을 리턴
def main():
l1 = [1, 3, 5, 7]
l2 = [2, 4, 6, 8]
l = list(map(lambda x, y : max(x, y), l1, l2))
print(l)
if __name__ == '__main__':
main()
#결과
[2, 4, 6, 8]
# Another common processing pattern,
# we've seen before is to filter a sequence.
# You start with some items and you end up with fewer of them.
def keep_evens(nums: list) -> list:
ret_list = []
for num in nums:
if num % 2 == 0:
ret_list.append(num)
return ret_list
print(keep_evens([1, 2, 3, 4, 5]))
filtered = filter((lambda x : x % 2 == 0), [1, 2, 3, 4, 5])
print(list(filtered))
# 결과
[2, 4]
[2, 4]
### filter
### 이터러블에서 특정 조건의 함수 결과가 True인 것만 추림
def getEvens(n):
if n % 2 ==0:
return True
def main():
r1 = list(filter(getEvens, [1, 2, 3, 4, 5]))
print('r1:', r1)
print('\t')
r2 = list(filter(lambda n : n % 2 == 0, [1, 2, 3, 4, 5]))
print('r2:', r2)
print('\t')
r3 = list(filter(lambda n : True if n % 2 == 0 else False, [1, 2, 3, 4, 5]))
print('r3:', r3)
if __name__ == '__main__':
main()
#결과
r1: [2, 4]
r2: [2, 4]
r3: [2, 4]
### reduce의 결과는 single value
import functools
def main():
ls = [1, 2, 3]
r = functools.reduce(lambda x, y: x + y, ls)
print(type(r))
print(r)
if __name__ == '__main__':
main()
#결과
<class 'int'>
6
### reduce 이터러블을 받아 연산 후에 연산 결과의 누적을 리턴
### pair에 대한 연산을 전체 이터러블로 확대할 때 사용
### 명시적인 loop 구현 없이 이터러블 처리
### 단일값만 리턴 (객체 리턴 X)
import functools
def main():
data = [{'name' : 'a', 'age' : 1},
{'name' : 'b', 'age' : 2}, {'name' : 'c', 'age' : 3}]
# 초기값이 없으면 에러 발생
r = functools.reduce(lambda x, y : x + y['age'], data, 0)
print(r)
if __name__ == '__main__':
main()
#결과
6
### reduce가 for-loop 없이 비슷한 효과를 낸다.
### 이런 특성을 이용해 문자열 합치기
import functools
def main():
ls = ['a', 'p', 'p', 'l', 'e']
s = functools.reduce(lambda x, y : x + y, ls)
print(type(s))
print(s)
if __name__ == '__main__':
main()
#결과
<class 'str'>
apple
### flattening a list of lists into a single list
import functools
def main():
list_2D = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
r = functools.reduce(lambda x, y : x + y, list_2D)
print(type(r))
print(r)
if __name__ == '__main__':
main()
#결과
<class 'list'>
[1, 2, 3, 4, 5, 6, 7, 8, 9]
### for-loop 없이 reduce를 사용해 함수 적용
import functools
def main():
ls = [11, 9, 12, 15, 7, 13]
r = functools.reduce(lambda x, y : min(x, y), ls)
print(type(r))
print('min:', r)
r = functools.reduce(lambda x, y : max(x, y), ls)
print(type(r))
print('max:', r)
if __name__ == '__main__':
main()
#결과
<class 'int'>
min: 7
<class 'int'>
max: 15
# ord(c, /)
# Return the Unicode code point for a one-character string.
o = (list(map(ord, 'hello')))
print(list(map(chr, o)))
# 결과
['h', 'e', 'l', 'l', 'o']
### 문자열 리스트를 받아 그중 가장 긴 문자열 출력
def makePairs(ls):
return dict(zip(ls, map(len, ls)))
def main():
pairs, ret = [], []
inList = ['aaa', 'bb', 'cccc', 'd', 'eeeeeeeeee']
pairs = makePairs(inList)
maxlen = max(pairs.values())
for k, v in pairs.items():
if v == maxlen:
ret.append(k)
print(ret)
pass
if __name__ == '__main__':
main()
# 결과
['eeeeeeeeee']
# 함수를 람다로 변경
pairs, result = [], []
inList = ['aaa', 'bb', 'cccc', 'd', 'eeeeeeeeee']
pairs = dict(zip(inList, map(lambda x: len(x), inList)))
max_length = max(pairs.values())
for k, v in pairs.items():
if v == max_length:
result.append(k)
print(pairs)
max_length_key = ''.join(result)
print(max_length_key + ':' + str(pairs.get(max_length_key)))
# 결과
{'aaa': 3, 'bb': 2, 'cccc': 4, 'd': 1, 'eeeeeeeeee': 10}
eeeeeeeeee:10
# 약간 더 간결하게 수정
# data format
# {'string': length} -> {'aa': 2}
results = []
inList = ['aaa', 'bb', 'cccc', 'd', 'eeeee', 'fffff']
pairs = dict(zip(inList, map(lambda x: len(x), inList)))
max_length = max(pairs.values())
for k, v in pairs.items():
if v == max_length:
results.append(k)
print('==========')
for max_length_key in results:
print(max_length_key + ':' + str(max_length))
print('==========')
# 결과
==========
eeeee:5
fffff:5
==========
# for-loop 안 쓰고 filter로 조건에 맞는 요소 추출
results = []
inList = ['aaa', 'bb', 'cccc', 'd', 'eeeee', 'fffff']
pairs = dict(zip(inList, map(lambda x: len(x), inList)))
# {'aaa': 3, 'bb': 2, 'cccc': 4, 'd': 1, 'eeeee': 5, 'fffff': 5}
# dict_items([('aaa', 3), ('bb', 2), ('cccc', 4), ('d', 1), ('eeeee', 5), ('fffff', 5)])
max_length = max(pairs.values())
results = list(filter(lambda pair: pair[1] == max_length, pairs.items()))
print(results)
# 결과
[('eeeee', 5), ('fffff', 5)]
# 다른 결과도 함께 출력
max_results, min_results, avg_results = [], [], []
inList = ['a', 'bb', 'ccc', 'dd', 'eeeee', 'fffff']
pairs = dict(zip(inList, map(lambda x: len(x), inList)))
max_length = max(pairs.values())
min_length = min(pairs.values())
avg_length = int(sum(pairs.values()) / len(inList))
max_results = list(filter(lambda pair: pair[1] == max_length, pairs.items()))
min_results = list(filter(lambda pair: pair[1] == min_length, pairs.items()))
avg_results = list(filter(lambda pair: pair[1] == avg_length, pairs.items()))
print('max len: ' + str(max_results))
print('min len: ' + str(min_results))
print('avg len: ' + str(avg_results))
# 결과
max len: [('eeeee', 5), ('fffff', 5)]
min len: [('a', 1)]
avg len: [('ccc', 3)]
def lenFunc(s):
return len(s)
x = map(lenFunc, ('apple', 'banana', 'cherry'))
print(list(x))
y = map(lambda x: len(x), ('apple', 'banana', 'cherry'))
print(list(y))
# 결과
[5, 6, 6]
[5, 6, 6]
l1 = [3, 4, 5]
l2 = [1, 2, 3]
ls = list(zip(l1, l2))
print(ls)
def zip_func(lst1: list, lst2: list) -> list:
ret = []
for idx in range(len(lst1)):
ret.append((lst1[idx], lst2[idx]))
return ret
zipped = zip_func(l1, l2)
print(zipped)
print("")
print(f"Are equal built-in zip and zip_func the same? {ls == zipped}")
# 결과
[(3, 1), (4, 2), (5, 3)]
[(3, 1), (4, 2), (5, 3)]
Are equal built-in zip and zip_func the same? True
ls1 = [1, 2, 3]
ls2 = [4, 5, 6]
ret1 = [sum(two_pairs) for two_pairs in list(zip(ls1, ls2))]
print(ret1)
ret2 = [n1 + n2 for (n1, n2) in list(zip(ls1, ls2))]
print(ret2)
print("")
print(f"Are equal ret1 and ret2 the same? {ret1 == ret2}")
# 결과
[5, 7, 9]
[5, 7, 9]
Are equal ret1 and ret2 the same? True
# The zip Function
l1 = [1, 2, 3]
l2 = ['a', 'b', 'c']
zipped = list(zip(l1, l2))
print(zipped)
zipped[-1] = 99, 'z'
print(zipped)
# main use-case
names = ['Niko', 'Ara', 'Kily']
group = [1, 2, 3]
score = [88, 99, 57]
for name, grp, sc in zip(names, group, score):
print(f"{name} from group {group} scored {sc}")
# 결과
[(1, 'a'), (2, 'b'), (3, 'c')]
[(1, 'a'), (2, 'b'), (99, 'z')]
Niko from group [1, 2, 3] scored 88
Ara from group [1, 2, 3] scored 99
Kily from group [1, 2, 3] scored 57
# Practical use-case of zip Function
# - Finding the lowest score
golfer1 = [5, 7, 4, 3, 8, 9]
golfer2 = [4, 8, 4, 4, 7, 4]
golfer3 = [6, 5, 4, 4, 4, 6]
lowest = []
for scores in zip(golfer1, golfer2, golfer3):
lowest.append(min(scores))
print(f"lowest scores: {lowest}")
win_count = {g: 0 for g in ('golfer1', 'golfer2', 'golfer3')}
# 개별 골퍼가 승리한 횟수 카운트
for idx in range(len(lowest)):
if lowest[idx] == golfer1[idx]:
win_count['golfer1'] += 1
if lowest[idx] == golfer2[idx]:
win_count['golfer2'] += 1
if lowest[idx] == golfer3[idx]:
win_count['golfer3'] += 1
print(f"win count of all golfers => {win_count}")
# 결과
lowest scores: [4, 5, 4, 3, 4, 4]
win count of all golfers => {'golfer1': 2, 'golfer2': 3, 'golfer3': 3}
# zip(seq1, seq2, ...)
num_first: list[int] = [1, 2, 3, 4, 5]
num_second: list[int] = [10, 20, 30, 40, 50]
num_third: list[int] = [100, 200, 300, 400, 500]
d = {n: [] for n in num_first}
nums_zip:zip = zip(num_first, num_second, num_third)
for f, s, t in nums_zip:
d[f] = [s, t]
print(d)
# 결과
{1: [10, 100], 2: [20, 200], 3: [30, 300], 4: [40, 400], 5: [50, 500]}
x = (lambda x, y: x+y) (1, 2)
print(x)
# Output
3
import itertools
seq1 = ["A", "B", "C", "D", "E", "F"]
seq2 = [1, 2, 3, 4]
seq3 = "xyz"
result = itertools.zip_longest(seq1, seq2, seq3, fillvalue="-")
print(list(result))
# Output:
[('A', 1, 'x'), ('B', 2, 'y'), ('C', 3, 'z'), ('D', 4, '-'), ('E', '-', '-'), ('F', '-', '-')]
댓글 영역