๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿ Algorithm/Python

[Python] Lambda ํ™œ์šฉ - map, filter, reduce ํ•จ์ˆ˜

by Danna 2020. 12. 7.
728x90
728x90

๋žŒ๋‹ค(Lambda)์˜ ํ™œ์šฉ

lambda ํ‚ค์›Œ๋“œ๋ฅผ ์ด์šฉํ•ด์„œ ์ด๋ฆ„ ์—†๋Š” ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.

lambda ๋งค๊ฐœ๋ณ€์ˆ˜ : ํ‘œํ˜„์‹

  • ํ•จ์ˆ˜๋ฅผ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋ฐ›๋Š” ํ•จ์ˆ˜(map, filter, reduce)์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜์—ฌ ์ฝ”๋“œ๋ฅผ ๊ฐ„๊ฒฐํ•˜๊ฒŒ ํ•œ๋‹ค.
  • ๊ฐ„๋‹จํ•œ ํ•จ์ˆ˜์˜ ๊ฒฝ์šฐ์— ์ฝ”๋“œ๋ฅผ ๊ฐ„๊ฒฐํ•˜๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•œ๋‹ค.
>>> (lambda x, y: x + y)(10, 20)
30

map ํ•จ์ˆ˜

map(function, iterable)

๋งค๊ฐœ๋ณ€์ˆ˜ function

  • map์˜ ๋งค๊ฐœ๋ณ€์ˆ˜ ํ•จ์ˆ˜์ž๋ฆฌ์—๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ 1๊ฐœ์ธ ํ•จ์ˆ˜๋งŒ ์ด์šฉ๊ฐ€๋Šฅํ•˜๋‹ค.
  • ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ 1๊ฐœ๊ฐ€ ์•„๋‹Œ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ TypeError๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. * ์˜ˆ์™ธ์ฒ˜๋ฆฌ ๊ฐ€๋Šฅ
  • ์ •์˜ํ•œ ํ•จ์ˆ˜๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ๋ณ€์ˆ˜๋ฅผ ์ธ์ž๋กœ ๋„˜๊ธฐ๊ฑฐ๋‚˜, lambda๋ฅผ ์ด์šฉํ•ด ์ž‘์„ฑํ•œ๋‹ค.

๋งค๊ฐœ๋ณ€์ˆ˜ iterble

  • ๋ฐ˜๋ณต๊ฐ€๋Šฅํ•œ object๋กœ list, tuple, string ๋“ฑ์„ ์ฃผ๋กœ ์‚ฌ์šฉํ•œ๋‹ค.

๋™์ž‘

  • ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋ฐ›์€ iterable์˜ ๊ฐ ์›์†Œ๋งˆ๋‹ค ํ•จ์ˆ˜๋ฅผ ์ ์šฉ์‹œํ‚จ ํ›„ ์ƒˆ๋กœ์šด ๋ฆฌ์ŠคํŠธ๋กœ ๋งŒ๋“ ๋‹ค.
  • ์ƒˆ๋กœ์šด object๋ฅผ ๋งŒ๋“ค๊ธฐ ๋•Œ๋ฌธ์— ๊ธฐ์กด์˜ ๋งค๊ฐœ๋ณ€์ˆ˜์—๋Š” ๋ณ€ํ™”๊ฐ€ ์—†๋‹ค.
  • ํ•จ์ˆ˜๋ฅผ ์ ์šฉ์‹œํ‚จ ์ƒˆ๋กœ์šด object๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
# map ํ•จ์ˆ˜
>>> def squares(x):
...     return x ** 2
...
>>> map(squares, range(5))
[0, 1, 4, 9, 16]

# map ํ•จ์ˆ˜์—์„œ์˜ lambda ์‘์šฉ
>>> map(lambda x: x ** 2, range(5))
[0, 1, 4, 9, 16]
>>> squared = map(lambda x: x** 2, range(5)) # ์—ฐ์‚ฐ ๊ฒฐ๊ณผ๋ฅผ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•ด squares์— ๋Œ€์ž…ํ•ด์ค˜์•ผํ•œ๋‹ค.
>>> map(lambda x:x+'@', "abcde") # string์— ๋Œ€ํ•ด map ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ํ•œ ๊ฒฝ์šฐ
['a@', 'b@', 'c@', 'd@', 'e@']

filter ํ•จ์ˆ˜

filter(function, iterable)

๋งค๊ฐœ๋ณ€์ˆ˜ function

  • filter์˜ ๋งค๊ฐœ๋ณ€์ˆ˜ ํ•จ์ˆ˜์ž๋ฆฌ์—๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ 1๊ฐœ์ธ ํ•จ์ˆ˜๋งŒ ์ด์šฉ๊ฐ€๋Šฅํ•˜๋‹ค.
  • ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ 1๊ฐœ๊ฐ€ ์•„๋‹Œ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ, TypeError๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. * ์˜ˆ์™ธ์ฒ˜๋ฆฌ ๊ฐ€๋Šฅ
  • ์ •์˜ํ•œ ํ•จ์ˆ˜๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ๋ณ€์ˆ˜๋ฅผ ์ธ์ž๋กœ ๋„˜๊ธฐ๊ฑฐ๋‚˜, lambda๋ฅผ ์ด์šฉํ•ด ์ž‘์„ฑํ•œ๋‹ค.

๋งค๊ฐœ๋ณ€์ˆ˜ iterble

  • ๋ฐ˜๋ณต๊ฐ€๋Šฅํ•œ object๋กœ list, tuple, string ๋“ฑ์„ ์ฃผ๋กœ ์‚ฌ์šฉํ•œ๋‹ค.

๋™์ž‘

  • ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋ฐ›์€ iterable์˜ ๊ฐ ์›์†Œ๋งˆ๋‹ค ํ•จ์ˆ˜๋ฅผ ์ ์šฉ์‹œํ‚จ ํ›„ ๊ฒฐ๊ณผ๊ฐ€ ์ฐธ์ธ ์›์†Œ๋“ค์„ ํ•„ํ„ฐ๋งํ•œ๋‹ค.
  • ๊ธฐ์กด์˜ iterble์€ ๋ณ€ํ™”๊ฐ€ ์—†๊ณ , ํ•จ์ˆ˜๋ฅผ ์ ์šฉ์‹œํ‚จ ์ƒˆ๋กœ์šด object๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
# filter ํ•จ์ˆ˜์—์„œ์˜ lambda ์‘์šฉ
>>> filter(lambda x: x%2 == 0, squared)
[0, 4, 16]
>>> filter(lambda x:x>'d', "bcdef")
'ef'

reduce ํ•จ์ˆ˜

reduce(function, iterable, initializer=None)

๋งค๊ฐœ๋ณ€์ˆ˜ function

  • reduce์˜ ๋งค๊ฐœ๋ณ€์ˆ˜ ํ•จ์ˆ˜์ž๋ฆฌ์—๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ 2๊ฐœ์ธ ํ•จ์ˆ˜๋งŒ ์ด์šฉ๊ฐ€๋Šฅํ•˜๋‹ค.
  • ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ 2๊ฐœ๊ฐ€ ์•„๋‹Œ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ, TypeError๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. (์˜ˆ์™ธ์ฒ˜๋ฆฌ ๊ฐ€๋Šฅ)
  • ์ •์˜ํ•œ ํ•จ์ˆ˜๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ๋ณ€์ˆ˜๋ฅผ ์ธ์ž๋กœ ๋„˜๊ธฐ๊ฑฐ๋‚˜, lambda๋ฅผ ์ด์šฉํ•ด ์ž‘์„ฑํ•œ๋‹ค.

๋งค๊ฐœ๋ณ€์ˆ˜ iterable

  • ๋ฐ˜๋ณต๊ฐ€๋Šฅํ•œ object๋กœ list, tuple, string ๋“ฑ์„ ์ฃผ๋กœ ์‚ฌ์šฉํ•œ๋‹ค.

๋งค๊ฐœ๋ณ€์ˆ˜ initializer

  • ์ธ์ž๋กœ ์ดˆ๊ธฐ๊ฐ’์€ ์ „๋‹ฌํ•œ๋‹ค๋ฉด, initializer์™€ ์ฒซ๋ฒˆ์งธ ์›์†Œ๋ฅผ ํ•จ์ˆ˜์— ์ ์šฉํ•œ๋‹ค.
  • ์ดˆ๊ธฐ๊ฐ’์„ ์ „๋‹ฌํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ, ์ฒซ๋ฒˆ์งธ ์›์†Œ์™€ ๋‘๋ฒˆ์งธ ์›์†Œ๋ฅผ ํ•จ์ˆ˜์— ์ ์šฉํ•œ๋‹ค.
# reduceํ•จ์ˆ˜์˜ ๋™์ž‘
def reduce(function, iterable, initializer=None):
  it = iter(iterable) # iterble์˜ ๋ฐ˜๋ณต์ž๋ฅผ it์— ์ €์žฅํ•œ๋‹ค.
  if initializer is None:
    value = next(it) # value์— iterable์˜ ์ฒซ๋ฒˆ์งธ ์š”์†Œ๋ฅผ ์ €์žฅํ•œ๋‹ค.
  else:
    value = initializer # initizlier๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ, value์— ๊ทธ ๊ฐ’์„ ์ €์žฅํ•œ๋‹ค.
  for element in it: # it ์˜ ์š”์†Œ๋ฅผ ์ฐจ๋ก€๋Œ€๋กœ element์— ์ €์žฅํ•œ๋‹ค.
    value = function(value, element) # value์™€ element๋ฅผ ํ•จ์ˆ˜์— ์ ์šฉํ•ด value์— ์ €์žฅํ•œ๋‹ค.
  return value # ์ตœ์ข… ๊ฒฐ๊ณผ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

๋™์ž‘

  • iter()ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•ด ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋ฐ›์€ iterable์˜ ๋ฐ˜๋ณต์ž๋ฅผ ๊บผ๋‚ด ๋ฐ˜ํ™˜ํ•ด it์— ์ €์žฅํ•œ๋‹ค.
  • initializer๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ, value์— iterable์˜ ์ฒซ๋ฒˆ์งธ ์š”์†Œ๋ฅผ ์ €์žฅํ•œ๋‹ค.
  • initializer๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ, value์— initializer ๊ฐ’์„ ์ €์žฅํ•œ๋‹ค.
  • for๋ฌธ์—์„œ it์˜ ์š”์†Œ๊ฐ’์„ ์ฐจ๋ก€๋Œ€๋กœ element์— ์ €์žฅํ•œ๋‹ค.
  • ๋ฐ˜๋ณต์ด ์ข…๋ฃŒ๋  ๋•Œ๊นŒ์ง€ value = function(value, element) ์—ฐ์‚ฐ์„ ๋ฐ˜๋ณตํ•ด ๊ฒฐ๊ณผ๊ฐ’์„ value์— ๋ˆ„์ ์‹œํ‚จ๋‹ค.
  • ๋ฐ˜๋ณต์ด ์ข…๋ฃŒ๋˜๋ฉด ์ตœ์ข… ๊ฒฐ๊ณผ๊ฐ’์ธ value๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
# reduce ํ•จ์ˆ˜์—์„œ์˜ lambda ์‘์šฉ
>>> reduce(lambda x, y: x+y, [0, 1, 2, 3, 4]) # ((((0+1)+2)+3)+4) = 10
10
>>> reduce(lambda x, y: x+y, [0, 1, 2, 3, 4], 10) # (((((10+0)+1)+2)+3)+4) = 20
20
>>> reduce(lambda x, y: x if x>y else y, [0, 1, 2, 3, 4])
4
# ์•„๋ž˜ ์ฝ”๋“œ์— ๋Œ€ํ•œ ๋™์ž‘ ๊ณผ์ •
>>> reduce(lambda x, y: x+y, [0, 1, 2, 3, 4]) # ((((0+1)+2)+3)+4)
10
# ๋™์ž‘ ์ฒซ๋ฒˆ์งธ(์›์†Œ1, ์›์†Œ2): 0 + 1 = 1(๊ฒฐ๊ณผ1)
# ๋™์ž‘ ๋‘๋ฒˆ์งธ(๊ฒฐ๊ณผ1, ์›์†Œ3): 1 + 2 = 3(๊ฒฐ๊ณผ2)
# ๋™์ž‘ ์„ธ๋ฒˆ์งธ(๊ฒฐ๊ณผ2, ์›์†Œ4): 3 + 3 = 6(๊ฒฐ๊ณผ3)
# ๋™์ž‘ ๋„ค๋ฒˆ์งธ(๊ฒฐ๊ณผ3, ์›์†Œ5): 6 + 4 = 10(๊ฒฐ๊ณผ4)
# ์ตœ์ข… ๋ฆฌํ„ด๊ฐ’ = 10

reduce์— ๋นˆ list๋ฅผ ์ธ์ž๋กœ ๋„˜๊ธธ ๊ฒฝ์šฐ ํ™•์ธํ•˜๊ธฐ

์ดˆ๊ธฐ ๊ฐ’ ์—†์ด reduceํ•จ์ˆ˜์— ๋นˆ list๋ฅผ ์ธ์ž๋กœ ๋„˜๊ธธ ๊ฒฝ์šฐ, TypeError๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. list๊ฐ€ ๋น„์–ด์žˆ๋”๋ผ๋„ initial value๋ฅผ ๋„˜๊ฒจ์ฃผ๋Š” ๊ฒฝ์šฐ, ์ •์ƒ์ ์œผ๋กœ ์ž‘๋™ํ•œ๋‹ค.

>>> reduce(lambda x, y: x+y, []) # ์ดˆ๊ธฐ๊ฐ’ ์—†์ด ๋นˆ list๋ฅผ ๋„˜๊ธธ ๊ฒฝ์šฐ
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: reduce() of empty sequence with no initial value

>>> reduce(lambda x, y: x+y, [], 10) # ์ดˆ๊ธฐ๊ฐ’์„ ๋„˜๊ฒจ์ค€ ๊ฒฝ์šฐ
10

Iterable, iterator ๊ฐ์ฒด

iterable ๊ฐ์ฒด์™€ iterator(๋ฐ˜๋ณต์ž) ๊ฐ์ฒด, iter() ํ•จ์ˆ˜์™€ next()ํ•จ์ˆ˜์— ๋Œ€ํ•ด

  • iterable ๊ฐ์ฒด๋Š” ๋ฐ˜๋ณต ๊ฐ€๋Šฅํ•œ ๊ฐ์ฒด๋ฅผ ๋œปํ•œ๋‹ค. list, dict, set, str, bytes, tuple, range ๋“ฑ์ด ์žˆ๋‹ค.
  • iterator ๊ฐ์ฒด๋Š” ๊ฐ’์„ ์ฐจ๋ก€๋Œ€๋กœ ๊บผ๋‚ผ ์ˆ˜ ์žˆ๋Š” ๊ฐ์ฒด๋ฅผ ๋œปํ•œ๋‹ค.
  • iter() ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด iterable ๊ฐ์ฒด๋ฅผ iterator(๋ฐ˜๋ณต์ž) ๊ฐ์ฒด๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.
    • iterable ๊ฐ์ฒด๋ฅผ ์ธ์ž๋กœ ๋ฐ›์•„, iterator๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
  • next() ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด iterator ๊ฐ์ฒด์˜ ์š”์†Œ ๊ฐ’์„ ํ•˜๋‚˜์”ฉ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ๋‹ค.
    • itertor ๊ฐ์ฒด๋ฅผ ์ธ์ž๋กœ ์ž…๋ ฅ๋ฐ›์•„ ๋‹ค์Œ ์š”์†Œ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
    • ๊ฐ์ฒด์—์„œ ๋” ๊ตฌํ•  ์š”์†Œ๊ฐ€ ์—†์œผ๋ฉด StopIteration์ด๋ผ๋Š” ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.
>>> a = [0, 1, 2]
>>> it = iter(a)
>>> type(it)
<type 'listiterator'>
>>> next(it) # a[0]
0
>>> next(it) # a[1]
1
>>> next(it) # a[2]
2
>>> next(it)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

  • 2019.07.15 ๊ณต๋ถ€ ์ž๋ฃŒ ์—…๋กœ๋“œ
  • reduce ํ•จ์ˆ˜์— ๋Œ€ํ•œ ์ดํ•ด๋Š” ๋ถ€์กฑํ•œ ๊ฒƒ ๊ฐ™๋‹ค.
728x90
728x90