partial.py

Functional Python Library


License
MIT
Install
pip install partial.py==0.1.4

Documentation

Functional Python Library - Partial.py

Site | Docs

Partial.py๋Š” ํ•จ์ˆ˜ํ˜• ํŒŒ์ด์ฌ์„ ๋” ๋งŽ์€ ์˜์—ญ์—์„œ ์‚ฌ์šฉํ•˜๊ณ ์ž, ๋ช‡ ๊ฐ€์ง€ ๊ธฐ๋Šฅ์„ ํ™•์žฅํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ž…๋‹ˆ๋‹ค. Partial.py๋Š” ๋ถ€๋ถ„ ์ ์šฉ, ํŒŒ์ดํ”„๋ผ์ธ, ๋น„๋™๊ธฐ ์ œ์–ด ๋“ฑ์˜ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์„ค์น˜ํ•˜๊ธฐ

Partial.py ์„ค์น˜

git์œผ๋กœ ์„ค์น˜ํ•˜๊ธฐ:
$ git clone https://github.com/marpple/partial.py.git
$ cd partial.py
$ sudo python setup.py install

ํ˜น์€

pypi๋กœ ์„ค์น˜ํ•˜๊ธฐ:
$ pip install partial.py

Partial.py ์‚ฌ์šฉ

๋„ค์ž„์ŠคํŽ˜์ด์Šค๋กœ ์‚ฌ์šฉํ•  _, __, ___๋ฅผ ๋ถˆ๋Ÿฌ์˜ต๋‹ˆ๋‹ค.

from partial import _, __, ___

๋” ๋‚˜์€ ๋ถ€๋ถ„ ์ ์šฉ (Partial application)

Partial.py๋Š” ์ด๋ฆ„์ฒ˜๋Ÿผ ๋ถ€๋ถ„ ์ ์šฉ(Partial application)์„ ์ค‘์š”ํ•˜๊ฒŒ ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ์กด์˜ _.partial ํ•จ์ˆ˜๋Š” ์™ผ์ชฝ์—์„œ๋ถ€ํ„ฐ๋งŒ ์ธ์ž๋ฅผ ์ ์šฉํ•ด๋‘˜ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Partial.py์˜ _.partial ํ•จ์ˆ˜๋Š” ๋งจ ์˜ค๋ฅธ์ชฝ ์ธ์ž๋‚˜ ๋งจ ์˜ค๋ฅธ์ชฝ์—์„œ ๋‘ ๋ฒˆ์งธ์—๋งŒ ์ธ์ž๋ฅผ ์ ์šฉํ•ด๋‘๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•˜๋ฉฐ, ์ƒˆ๋กœ์šด ๊ตฌ๋ถ„์ž์ธ ___๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์ค‘๊ฐ„ ์ง€์ ์— ์ธ์ž๊ฐ€ ๊ฐ€๋ณ€์ ์œผ๋กœ ์ ์šฉ๋˜๋„๋ก ๋น„์›Œ๋‘˜ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

_.partial์˜ ์ผ๋ฐ˜์  ์‚ฌ์šฉ

_.partial์„ ์‹คํ–‰ํ•˜๋ฉด์„œ ์ธ์ž ์ž๋ฆฌ์— _๋ฅผ ๋„˜๊ธฐ๋ฉด ๋ถ€๋ถ„ ์ ์šฉํ•  ์ธ์ž๋ฅผ ๊ฑด๋„ˆ๋Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. _๋ฅผ ์ด์šฉํ•˜๋ฉด ์›ํ•˜๋Š” ๊ณณ์—๋งŒ ์ธ์ž๋ฅผ ๋ถ€๋ถ„ ์ ์šฉํ•ด๋‘˜ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. _๊ฐ€ ์žˆ๋Š” ์ž๋ฆฌ๋Š” ์ดํ›„ ์‹คํ–‰์‹œ ์ฑ„์›Œ์ง‘๋‹ˆ๋‹ค.

pc = _.partial(print, 1)
pc(2)
# ๊ฒฐ๊ณผ: 1 2
# 2 ๊ฐ€ ์˜ค๋ฅธ์ชฝ์œผ๋กœ ๋“ค์–ด๊ฐ‘๋‹ˆ๋‹ค.
pc(2, 3)
# ๊ฒฐ๊ณผ: 1 2 3
# 2, 3์ด ์˜ค๋ฅธ์ชฝ์œผ๋กœ ๋“ค์–ด๊ฐ‘๋‹ˆ๋‹ค.

pc = _.partial(print, _, 2)
pc(1)
# ๊ฒฐ๊ณผ: 1 2
# 1์ด ์™ผ์ชฝ์˜ _ ์ž๋ฆฌ์— ๋“ค์–ด๊ฐ‘๋‹ˆ๋‹ค.
pc(1, 3)
# ๊ฒฐ๊ณผ: 1 2 3
# 1์ด ์™ผ์ชฝ์˜ _ ์ž๋ฆฌ์— ๋“ค์–ด๊ฐ€๊ณ  3์ด ์˜ค๋ฅธ์ชฝ์œผ๋กœ ๋“ค์–ด๊ฐ‘๋‹ˆ๋‹ค.

pc = _.partial(print, _, _, 3)
pc(1)
# ๊ฒฐ๊ณผ: 1 undefined 3
# 1์ด ์™ผ์ชฝ์˜ _ ์ž๋ฆฌ์— ๋“ค์–ด๊ฐ€๊ณ  ๋‘ ๋ฒˆ์งธ _๋Š” ๋“ค์–ด์˜ค์ง€ ์•Š์•„ undefined๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.
pc(1, 2)
# ๊ฒฐ๊ณผ: 1 2 3
# 1๊ณผ 2๊ฐ€ ์ˆœ์„œ๋Œ€๋กœ _, _๋ฅผ ์ฑ„์›๋‹ˆ๋‹ค.
pc(1, 2, 4)
# ๊ฒฐ๊ณผ: 1 2 3 4
# 1๊ณผ 2๊ฐ€ ์ˆœ์„œ๋Œ€๋กœ _, _๋ฅผ ์ฑ„์šฐ๊ณ  3์˜ ์˜ค๋ฅธ์ชฝ์œผ๋กœ 4๊ฐ€ ๋“ค์–ด๊ฐ‘๋‹ˆ๋‹ค.

pc = _.partial(print, _, 2, _, 4)
pc(1, 3, 5)
# ๊ฒฐ๊ณผ: 1 2 3 4 5
# 1์„ _ ์ž๋ฆฌ์— ์ฑ„์šฐ๊ณ  2๋ฅผ ๋„˜๊ฒจ์„œ _์— 3์„ ์ฑ„์šฐ๊ณ  4์˜ ์˜ค๋ฅธ์ชฝ์— 5๊ฐ€ ๋“ค์–ด๊ฐ‘๋‹ˆ๋‹ค.

pc = _.partial(print, _, 2, _, _, 5)
pc(1, 3, 4, 6)
# ๊ฒฐ๊ณผ: 1 2 3 4 5 6
# 1์„ _ ์ž๋ฆฌ์— ์ฑ„์šฐ๊ณ  2๋ฅผ ๋„˜๊ฒจ์„œ _์— 3์„ ์ฑ„์šฐ๊ณ  ๋‹ค์Œ _์— 4๋ฅผ ์ฑ„์šฐ๊ณ  5์˜ ์˜ค๋ฅธ์ชฝ์— 6์ด ๋“ค์–ด๊ฐ‘๋‹ˆ๋‹ค.

์˜ค๋ฅธ์ชฝ์—์„œ๋ถ€ํ„ฐ ์ธ์ž ์ ์šฉํ•ด๋‘๊ธฐ

_.partial์„ ์‹คํ–‰ํ•˜๋ฉด ___๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์™ผํŽธ์˜ ์ธ์ž๋“ค์„ ์™ผ์ชฝ๋ถ€ํ„ฐ ์ ์šฉํ•˜๊ณ  ์˜ค๋ฅธํŽธ์˜ ์ธ์ž๋“ค์„ ์˜ค๋ฅธ์ชฝ๋ถ€ํ„ฐ ์ ์šฉํ•  ์ค€๋น„๋ฅผ ํ•ด๋‘” ํ•จ์ˆ˜๋ฅผ ๋ฆฌํ„ดํ•ฉ๋‹ˆ๋‹ค. ๋ถ€๋ถ„ ์ ์šฉ๋œ ํ•จ์ˆ˜๋ฅผ ๋‚˜์ค‘์— ์‹คํ–‰ํ•˜๋ฉด ๊ทธ๋•Œ ๋ฐ›์€ ์ธ์ž๋“ค๋กœ ์™ผ์ชฝ๊ณผ ์˜ค๋ฅธ์ชฝ์„ ๋จผ์ € ์ฑ„์šด ํ›„, ๋‚จ์€ ์ธ์ž๋“ค๋กœ ๊ฐ€์šด๋ฐ ___ ์ž๋ฆฌ๋ฅผ ์ฑ„์›๋‹ˆ๋‹ค.

pc = _.partial(print, ___, 2, 3)
pc(1)
# ๊ฒฐ๊ณผ: 1 2 3
# ___ ์ž๋ฆฌ์— 1์ด ๋“ค์–ด๊ฐ€๊ณ  2, 3์€ ๋งจ ์˜ค๋ฅธ์ชฝ์— ๋“ค์–ด๊ฐ‘๋‹ˆ๋‹ค.
pc(1, 4, 5, 6)
# ๊ฒฐ๊ณผ: 1 4 5 6 2 3
# ___ ์ž๋ฆฌ์— 1, 4, 5, 6์ด ๋“ค์–ด๊ฐ€๊ณ  2, 3์€ ๋งจ ์˜ค๋ฅธ์ชฝ์— ๋“ค์–ด๊ฐ‘๋‹ˆ๋‹ค.

pc = _.partial(print, _, 2, ___, 6)
pc(1, 3, 4, 5)
# ๊ฒฐ๊ณผ: 1 2 3 4 5 6
# _์— 1์ด ๋“ค์–ด๊ฐ€๊ณ  2๋ฅผ ๋„˜์–ด๊ฐ€๊ณ  ___ ์ž๋ฆฌ์— 3, 4, 5๊ฐ€ ์ฑ„์›Œ์ง€๊ณ  6์ด ๋งจ ์˜ค๋ฅธ์ชฝ์— ๋“ค์–ด๊ฐ‘๋‹ˆ๋‹ค.
pc(1, 3, 4, 5, 7, 8, 9)
# ๊ฒฐ๊ณผ: 1 2 3 4 5 7 8 9 6
# _์— 1์ด ๋“ค์–ด๊ฐ€๊ณ  2๋ฅผ ๋„˜์–ด๊ฐ€๊ณ  ___ ์ž๋ฆฌ์— 3, 4, 5, 7, 8, 9๊ฐ€ ์ฑ„์›Œ์ง€๊ณ  6์ด ๋งจ ์˜ค๋ฅธ์ชฝ์— ๋“ค์–ด๊ฐ‘๋‹ˆ๋‹ค.

pc = _.partial(print, _, 2, ___, 5, _, 7)
pc(1)
# ๊ฒฐ๊ณผ: 1 2 5 undefined 7
# _ ์ž๋ฆฌ์— 1์ด ๋“ค์–ด๊ฐ€๊ณ  2์™€ 5์‚ฌ์ด๋Š” ์œ ๋™์ ์ด๋ฏ€๋กœ ๋ชจ์ด๊ณ  5๊ฐ€ ๋“ค์–ด๊ฐ„ ํ›„ _๊ฐ€ undefined๋กœ ๋Œ€์ฒด ๋˜๊ณ  7์ด ๋“ค์–ด๊ฐ‘๋‹ˆ๋‹ค.
pc(1, 3, 4)
# ๊ฒฐ๊ณผ: 1 2 3 5 4 7
# _ ์ž๋ฆฌ์— 1์ด ๋“ค์–ด๊ฐ€๊ณ  2์™€ 5์‚ฌ์ด์— 3์ด ๋“ค์–ด๊ฐ€๊ณ  _ ๋ฅผ 4๋กœ ์ฑ„์šด ํ›„ 7์ด ๋“ค์–ด๊ฐ‘๋‹ˆ๋‹ค.
# ์™ผ์ชฝ์˜ _ ๋“ค์ด ์šฐ์„  ์ˆœ์œ„๊ฐ€ ์ œ์ผ ๋†’๊ณ  ___ ๋ณด๋‹ค ์˜ค๋ฅธ์ชฝ์˜ _ ๋“ค์ด ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋†’์Šต๋‹ˆ๋‹ค.
pc(1, 3, 4, 6, 8)
# ๊ฒฐ๊ณผ: 1 2 3 4 6 5 8 7
# _ ์ž๋ฆฌ์— 1์ด ๋“ค์–ด๊ฐ€๊ณ  2์™€ 5์‚ฌ์ด์— 3, 4, 6์ด ๋“ค์–ด๊ฐ€๊ณ  _ ๋ฅผ 8๋กœ ์ฑ„์šด ํ›„ 7์ด ๋“ค์–ด๊ฐ‘๋‹ˆ๋‹ค.

๊ฐ„๊ฒฐํ•˜๊ฒŒ ์‚ฌ์šฉํ•˜๊ธฐ

_ == _.partial์ž…๋‹ˆ๋‹ค. _.partial์„ _๋กœ ๊ฐ„๊ฒฐํ•˜๊ฒŒ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

def add (a, b): 
  return a + b
  
add10 = _(add, 10)
print( add10(5) )
# 15

ํŒŒ์ดํ”„๋ผ์ธ

ํŒŒ์ดํ”„๋ผ์ธ ํ•จ์ˆ˜์ธ _.pipe, _.go ๋“ฑ์€ ์ž‘์€ ํ•จ์ˆ˜๋“ค์„ ๋ชจ์•„ ํฐ ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“œ๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค. ํŒŒ์ดํ”„๋ผ์ธ์œผ๋กœ ํ•จ์ˆ˜๋ฅผ ์กฐํ•ฉํ•˜๋ฉด ์™ผ์ชฝ์—์„œ๋ถ€ํ„ฐ ์˜ค๋ฅธ์ชฝ, ์œ„์—์„œ๋ถ€ํ„ฐ ์•„๋ž˜๋กœ ํ‘œํ˜„๋˜์–ด ์ฝ๊ธฐ ์‰ฌ์šด ์ฝ”๋“œ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ์ฒด์ธ ๋ฐฉ์‹๊ณผ ๋‹ค๋ฅด๊ฒŒ ์•„๋ฌด ํ•จ์ˆ˜๋‚˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด ์ž์œ ๋„๊ฐ€ ๋†’์Šต๋‹ˆ๋‹ค. ์ž‘์€ ํ•จ์ˆ˜๋“ค์„ ์ธ์ž์™€ ๊ฒฐ๊ณผ๋งŒ์„ ์ƒ๊ฐํ•˜๋ฉด์„œ ์กฐํ•ฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

์ฆ‰์‹œ ์‹คํ–‰๊ณผ Multiple Results

_.go๋Š” ํŒŒ์ดํ”„๋ผ์ธ์˜ ์ฆ‰์‹œ ์‹คํ–‰ ๋ฒ„์ „์ž…๋‹ˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ ์ธ์ž๋กœ ๋ฐ›์€ ๊ฐ’์„ ๋‘ ๋ฒˆ์งธ ์ธ์ž๋กœ ๋ฐ›์€ ํ•จ์ˆ˜์—๊ฒŒ ๋„˜๊ฒจ์ฃผ๊ณ  ๋‘ ๋ฒˆ์งธ ์ธ์ž๋กœ ๋ฐ›์€ ํ•จ์ˆ˜์˜ ๊ฒฐ๊ณผ๋Š” ์„ธ ๋ฒˆ์งธ ํ•จ์ˆ˜์—๊ฒŒ ๋„˜๊ฒจ์ฃผ๋Š” ๊ฒƒ์„ ๋ฐ˜๋ณตํ•˜๋‹ค๊ฐ€ ๋งˆ์ง€๋ง‰ ํ•จ์ˆ˜์˜ ๊ฒฐ๊ณผ๋ฅผ ๋ฆฌํ„ดํ•ด์ค๋‹ˆ๋‹ค.

_.go(10, # ์ฒซ ๋ฒˆ์งธ ํ•จ์ˆ˜์—์„œ ์‚ฌ์šฉํ•  ์ธ์ž
  lambda a: a * 10, # ์—ฐ์† ์‹คํ–‰ํ•  ํ•จ์ˆ˜ 1
  # 100
  lambda a: a - 50, # ์—ฐ์† ์‹คํ–‰ํ•  ํ•จ์ˆ˜ 2
  # 50
  lambda a: a + 10) # ์—ฐ์† ์‹คํ–‰ํ•  ํ•จ์ˆ˜ 3
  # 60

_.go๋Š” Multiple Results๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. _.mr ํ•จ์ˆ˜๋ฅผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋ฉด ๋‹ค์Œ ํ•จ์ˆ˜์—๊ฒŒ 2๊ฐœ ์ด์ƒ์˜ ์ธ์ž๋“ค์„ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

_.go(10, # ์ฒซ ๋ฒˆ์งธ ํ•จ์ˆ˜์—์„œ ์‚ฌ์šฉํ•  ์ธ์ž
  lambda a: _.mr(a * 10, 50), # ๋‘ ๊ฐœ์˜ ๊ฐ’์„ ๋ฆฌํ„ด
  lambda a, b: a - b, # ๋‘ ๊ฐœ์˜ ์ธ์ž ๋ฐ›๊ธฐ
  lambda a: a + 10)
  # 60

_.go์˜ ์ฒซ ๋ฒˆ์งธ ์ธ์ž๋Š” ๋‘ ๋ฒˆ์งธ ์ธ์ž์ธ ํ•จ์ˆ˜๊ฐ€ ์‚ฌ์šฉํ•  ์ธ์ž๊ณ  ๋‘ ๋ฒˆ์งธ ๋ถ€ํ„ฐ๋Š” ํŒŒ์ดํ”„๋ผ์ธ์—์„œ ์‚ฌ์šฉํ•  ํ•จ์ˆ˜๋“ค์ž…๋‹ˆ๋‹ค. _.go์˜ ๋‘ ๋ฒˆ์งธ ์ธ์ž์ธ ํ•จ์ˆ˜, ์ฆ‰ ์ตœ์ดˆ ์‹คํ–‰๋  ํ•จ์ˆ˜์—๊ฒŒ 2๊ฐœ ์ด์ƒ์˜ ์ธ์ž๋ฅผ ๋„˜๊ธฐ๊ณ ์ž ํ•œ๋‹ค๋ฉด _.mr์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. _.mr๋กœ ์ธ์ž๋“ค์„ ๊ฐ์‹ธ์„œ ๋„˜๊ฒจ์ฃผ๋ฉด, ๋‹ค์Œ ํ•จ์ˆ˜๋Š” ์ธ์ž๋ฅผ ์—ฌ๋Ÿฌ ๊ฐœ๋กœ ํŽผ์ณ์„œ ๋ฐ›๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

_.go(_.mr(2, 3),
  lambda a, b: a + b, # 2 + 3
  lambda a: a * a)
  # 25

_.go๋ฅผ ์ด๋ฏธ ์ •์˜๋˜์–ด ์žˆ๋Š” ํ•จ์ˆ˜์™€ ์กฐํ•ฉํ•˜๋ฉด ๋”์šฑ ์ฝ๊ธฐ ์ข‹์•„์ง‘๋‹ˆ๋‹ค.

def add(a, b):
  return a + b
  
def square(a):
  return a * a
  
_.go(_.mr(2, 3), add, square)
# 25

ํŒŒ์ดํ”„๋ผ์ธ ํ•จ์ˆ˜๋ฅผ ๋ฆฌํ„ดํ•˜๋Š” _.pipe

_.go๊ฐ€ ์ฆ‰์‹œ ์‹คํ–‰ํ•˜๋Š” ํŒŒ์ดํ”„๋ผ์ธ์ด๋ผ๋ฉด _.pipe๋Š” ์‹คํ–‰ํ•  ์ค€๋น„๊ฐ€ ๋œ ํ•จ์ˆ˜๋ฅผ ๋ฆฌํ„ดํ•˜๋Š” ํŒŒ์ดํ”„๋ผ์ธ ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค. ๊ทธ์™ธ ๋ชจ๋“  ๊ธฐ๋Šฅ์€ _.go์™€ ๋™์ผํ•ฉ๋‹ˆ๋‹ค.

f1 = _.pipe(add, square)
f1(2, 3)
# 25

๋ถ€๋ถ„ ์ปค๋ง

์ปค๋ง์ด ๋ถ€๋ถ„์ ์œผ๋กœ ๋™์ž‘ํ•˜๋Š” ํ•จ์ˆ˜

Partial.py์˜ ์ฃผ์š” ํ•จ์ˆ˜๋“ค์€ ์ปค๋ง์ด ๋ถ€๋ถ„์ ์œผ๋กœ ๋™์ž‘ํ•˜๋„๋ก ์ง€์›ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜๋Š” ์ผ๋ฐ˜์ ์ธ ์‚ฌ์šฉ ๋ชจ์Šต์ž…๋‹ˆ๋‹ค.

์ผ๋ฐ˜์ ์ธ ๋ฐฉ์‹:
values = lambda data: _.map(data, lambda v, *r: v)
print(values({ 'a': 1, 'b': 2, 'c': 4 }))
# [1, 2, 4]

take3 = lambda data: _.take(data, 3)
take3([1, 2, 3, 4, 5])
# [1, 2, 3]

Partial.py์˜ ์ฃผ์š” ํ•จ์ˆ˜๋“ค์€ ๋ถ€๋ถ„ ์ปค๋ง์ด ์ ์šฉ๋˜์–ด ์œ„์™€ ๋™์ผํ•œ ๋™์ž‘์„ ์•„๋ž˜์™€ ๊ฐ™์ด ๊ฐ„๊ฒฐํ•˜๊ฒŒ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ถ€๋ถ„ ์ปค๋ง์ด ์ง€์›๋  ๊ฒฝ์šฐ:
values = _.map(lambda v, *r: v)
print(values({ 'a': 1, 'b': 2, 'c': 4 }))
# [1, 2, 4]

take3 = _.take(3)
take3([1, 3, 5, 7, 9])
# [1, 3, 5]

ํŒŒ์ดํ”„๋ผ์ธ๊ณผ ํ•จ๊ป˜

๋ถ€๋ถ„ ์ปค๋ง์ด ์ง€์›๋˜๋ฉด ํŒŒ์ดํ”„๋ผ์ธ๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ๋•Œ, ์ฒด์ธ์ฒ˜๋Ÿผ ๊ฐ„๊ฒฐํ•œ ํ‘œํ˜„์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

users = [
  { 'id': 1, 'name': 'ID', 'age': 32 },
  { 'id': 2, 'name': 'HA', 'age': 25 },
  { 'id': 3, 'name': 'BJ', 'age': 32 },
  { 'id': 4, 'name': 'PJ', 'age': 28 },
  { 'id': 5, 'name': 'JE', 'age': 27 },
  { 'id': 6, 'name': 'JM', 'age': 32 },
  { 'id': 7, 'name': 'JI', 'age': 31 }
]

## ์ผ๋ฐ˜์ ์ธ ์‚ฌ์šฉ
_.go(users,
  lambda users: _.filter(users, lambda u, *r: u['age'] < 30),
  lambda users: _.pluck(users, 'name'),
  print)
# ['HA', 'PJ', 'JE']

## ๋ถ€๋ถ„ ์ปค๋ง์ด ๋œ๋‹ค๋ฉด
_.go(users,
  _.filter(lambda u, *r: u['age'] < 30),
  _.pluck('name'),
  print)
# ['HA', 'PJ', 'JE']

## Underscore.py ์ฒด์ธ
underscore\
  .chain(users)\
  .filter(lambda u: u['age'] < 30)\
  .pluck('name')\
  .tap(print)
# ['HA', 'PJ', 'JE']

_.go, _.pipe ๋“ฑ์˜ ํŒŒ์ดํ”„๋ผ์ธ์ด ๋ฐ›๋Š” ์žฌ๋ฃŒ๋Š” ํ•จ์ˆ˜์ด๊ธฐ ๋•Œ๋ฌธ์— ์•„๋ฌด ํ•จ์ˆ˜๋‚˜ ์กฐํ•ฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฒด์ธ์ฒ˜๋Ÿผ ๋ฉ”์„œ๋“œ ๋“ฑ์œผ๋กœ ์ค€๋น„๋˜์–ด์žˆ์ง€ ์•Š์•„๋„ ๋˜๋ฉฐ Partial.py์˜ ํ•จ์ˆ˜๋งŒ ์‚ฌ์šฉํ•  ํ•„์š”๋„ ์—†์Šต๋‹ˆ๋‹ค. Partial.py์˜ ํŒŒ์ดํ”„๋ผ์ธ์€ ๊ฒฐ๊ณผ๋ฅผ ์—ฌ๋Ÿฌ ๊ฐœ๋กœ ๋ฆฌํ„ดํ•  ์ˆ˜ ์žˆ๊ณ , ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์ธ์ž๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ๊ณ , ๋‹ค๋ฅธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ์žˆ๋Š” ํ•จ์ˆ˜๋“ , ์ง์ ‘ ๋งŒ๋“  ํ•จ์ˆ˜๋“ , ์ต๋ช… ํ•จ์ˆ˜๋“  ๋ชจ๋‘ ์‰ฝ๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

products = [
  { 'id': 1, 'name': 'ํ›„๋“œ ์ง‘์—…', 'discounted_price': 6000, 'price': 10000  },
  { 'id': 2, 'name': '์ฝ”์žผ ํ›„๋“œํ‹ฐ', 'discounted_price': 8000, 'price': 8000  },
  { 'id': 3, 'name': 'A1 ๋ฐ˜ํŒ”ํ‹ฐ', 'discounted_price': 6000, 'price': 6000  },
  { 'id': 4, 'name': '์ฝ”์žผ ๋ฐ˜ํŒ”ํ‹ฐ', 'discounted_price': 5000, 'price': 6000  }
]

# ํ• ์ธ ์ƒํ’ˆ๋“ค์„ ๊ฐ€๊ฒฉ์ด ๋‚ฎ์€ ์ˆœ์œผ๋กœ ์ •๋ ฌํ•œ ์ƒํ’ˆ ์ด๋ฆ„๋“ค
_.go(products,
  _.filter(lambda p, *r: p['price'] > p['discounted_price']),
  _.sortBy('discounted_price'),
  _.pluck('name'),
  print)
  # ['์ฝ”์žผ ๋ฐ˜ํŒ”ํ‹ฐ', 'ํ›„๋“œ ์ง‘์—…']

# ํ• ์ธ์ด ์—†๋Š” ์ƒํ’ˆ๋“ค์˜ id๋“ค
_.go(products,
  _.reject(lambda p, *r: p['price'] > p['discounted_price']),
  _.pluck('id'),
  print)
  # [2, 3]

# ํ• ์ธ ์ƒํ’ˆ ์ค‘ ํ• ์ธ์•ก์ด ๊ฐ€์žฅ ๋‚ฎ์€ ์ƒํ’ˆ์˜ ์ด๋ฆ„
_.go(products,
  _.filter(lambda p, *r: p['price'] > p['discounted_price']),
  _.min(lambda p, *r: p['price'] - p['discounted_price']),
  _.val('name'),
  print)
  # ์ฝ”์žผ ๋ฐ˜ํŒ”ํ‹ฐ

# ํ• ์ธ์•ก์ด ๊ฐ€์žฅ ๋†’์€ ์ƒํ’ˆ์˜ ์ด๋ฆ„
_.go(products,
  _.max(lambda p, *r: p['price'] - p['discounted_price']),
  _.val('name'),
  print)
  # ํ›„๋“œ ์ง‘์—…

๋น„๋™๊ธฐ

async, await ํ‚ค์›Œ๋“œ์™€ Partial.py๋ฅผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋ฉด ๋‹ค์–‘ํ•œ ๋น„๋™๊ธฐ ์ƒํ™ฉ์„ ๊ฐ„๋‹จํžˆ ์ œ์–ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํŒŒ์ดํ”„๋ผ์ธ์œผ๋กœ ๋น„๋™๊ธฐ ์ œ์–ด ํ•˜๊ธฐ

_.asy๋ฅผ ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋กœ ๊ฐ–๋Š” _.asy.go, _.asy.pipe ๋“ฑ์˜ ํŒŒ์ดํ”„๋ผ์ธ ํ•จ์ˆ˜๋“ค์€ ๋น„๋™๊ธฐ ์ œ์–ด๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

await ํ‚ค์›Œ๋“œ์™€ ํ•จ๊ป˜ ์‚ฌ์šฉ:
async def asy_add(val, *r):
  await asyncio.sleep(1)
  return val + 10
  
## await ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋ฐ”๋กœ ์‹คํ–‰ํ•˜๋Š” _.go.asy
await _.asy.go(10,
  asy_add,
  print)
  # 20
  
## _.asy.pipe๋กœ ๋น„๋™๊ธฐ ํ•จ์ˆ˜์™€ ๋™๊ธฐ ํ•จ์ˆ˜ ์กฐํ•ฉํ•ด ๋งŒ๋“  ์ƒˆ๋กœ์šด ํ•จ์ˆ˜
asy_pipe = _.asy.pipe(asy_add, print)
await asy_pipe(10) 
# 20

## _.pipe๋Š” ๋น„๋™๊ธฐ ํ•จ์ˆ˜๋ฅผ ๋งŒ๋‚˜๋ฉด ์ž๋™์œผ๋กœ _.asy.pipe๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.
asy_pipe = _.pipe(asy_add, print)
await asy_pipe(10)
# 20

์ปฌ๋ ‰์…˜์„ ๋‹ค๋ฃจ๋Š” ๋น„๋™๊ธฐ ์ œ์–ด ํ•จ์ˆ˜

Partial.py์˜ _.each, _.map, _.reduce ๋“ฑ์˜ ์ฃผ์š” ํ•จ์ˆ˜๋“ค์€ _.asy.go์™€ _.asy.pipe์ฒ˜๋Ÿผ ๋™๊ธฐ์™€ ๋น„๋™๊ธฐ ์ƒํ™ฉ์ด ๋ชจ๋‘ ๋Œ€์‘๋˜๋„๋ก ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. Partial.py์˜ ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•˜๋ฉด ๋น„๋™๊ธฐ ์ƒํ™ฉ์—์„œ๋„ ๋™๊ธฐ ์ƒํ™ฉ๊ณผ ๋™์ผํ•œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๊ณ , ๋น„๋™๊ธฐ ํ•จ์ˆ˜์™€ ๋™๊ธฐ ํ•จ์ˆ˜์˜ ์กฐํ•ฉ๋„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

async def asyncDate(*r):
  await asyncio.sleep(1)
  return datetime.datetime.now()

def syncDate(*r):
  return datetime.datetime.now()

_.go(
  [1, 2, 3],
  _.map(syncDate),
  _.map(lambda now, *r: now.strftime('%Y-%m-%d %H:%M:%S')),
  print)
# ['2017-06-16 12:34:39', '2017-06-16 12:34:39', '2017-06-16 12:34:39']

await _.asy.go(
  [1, 2, 3],
  _.map(asyncDate),
  _.map(lambda now, *r: now.strftime('%Y-%m-%d %H:%M:%S')),
  print)
# ['2017-06-16 12:34:39', '2017-06-16 12:34:39', '2017-06-16 12:34:39']

์œ„ ์‚ฌ๋ก€์ฒ˜๋Ÿผ Partial.py๋Š” _.pipe, _.each, _.map, _.find, _.filter, _.reject, _.reduce, _.some, _.every ๋“ฑ์˜ ํ•จ์ˆ˜๋“ค์—์„œ ์ž๋™ ๋น„๋™๊ธฐ ์ œ์–ด ๋กœ์ง์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

์ง€์—ฐ ํ‰๊ฐ€ L

Partial.py์˜ L์„ ์ด์šฉํ•˜๋ฉด, ํŒŒ์ดํ”„๋ผ์ธ ๋‚ด๋ถ€์—์„œ ํ•จ์ˆ˜๋“ค์˜ ์‹คํ–‰ ์ˆœ์„œ๋ฅผ ์žฌ๋ฐฐ์น˜ํ•˜์—ฌ ์ ์ ˆํ•˜๊ฒŒ ํ‰๊ฐ€๋ฅผ ์ง€์—ฐํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ๋ฒ•์€ ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค. Partial.py์—์„œ L์„ importํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. L์„ ํ†ตํ•ด ์ง€์—ฐ ํ‰๊ฐ€ํ•  ์˜์—ญ์„ ๋ช…์‹œ์ ์œผ๋กœ ์„ ํƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. _.go, _.pipe๋“ฑ์˜ ํŒŒ์ดํ”„๋ผ์ธ์ด L๋กœ ์‹œ์ž‘ํ•˜์—ฌ L๋กœ ๋๋‚  ๋•Œ๊นŒ์ง€์˜ ํ•จ์ˆ˜๋“ค์„ ์žฌ๋ฐฐ์น˜ํ•˜์—ฌ ์„ฑ๋Šฅ์„ ๊ฐœ์„ ํ•ฉ๋‹ˆ๋‹ค.

๋น„๊ต

์—„๊ฒฉํ•œ ํ‰๊ฐ€:
list = [1, 2, 3, 4, 5, 6]
_.go(list,
  _.map(lambda v, *r: v * v), # 6๋ฒˆ
  _.filter(lambda v, *r: v < 20), # 6๋ฒˆ
  _.take(2),
  print)
# [1, 4]
# ์ด 12๋ฒˆ
์ง€์—ฐ ํ‰๊ฐ€:
list = [1, 2, 3, 4, 5, 6]
_.go(list,
  L.map(lambda v, *r: v * v), # 2๋ฒˆ
  L.filter(lambda v, *r: v < 20), # 2๋ฒˆ
  L.take(2),
  print)
# [1, 4]
# ์ด 4๋ฒˆ  

์ง€์› ํ•จ์ˆ˜๋“ค

Partial.js์˜ ์ง€์—ฐ ํ‰๊ฐ€ ์ง€์› ํ•จ์ˆ˜๋กœ๋Š” L.map, L.filter, L.reject, L.find, L.some, L.every, L.take๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ํ•จ์ˆ˜๋“ค์„ ์ˆœ์„œ๋Œ€๋กœ ๋‚˜์—ดํ•˜๋ฉด ํŒŒ์ดํ”„๋ผ์ธ์ด ํ‰๊ฐ€ ์‹œ์ ์„ ๋ณ€๊ฒฝํ•˜์—ฌ ์„ฑ๋Šฅ์„ ๊ฐœ์„ ํ•ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ƒํ™ฉ ๋“ฑ์—์„œ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.

  • map->map->map
  • map->take
  • filter->take
  • map->filter->take
  • map->filter->map->map
  • map->filter->map->take
  • map->reject->map->map->filter->map
  • map->some
  • map->every
  • map->find
  • map->filter->some
  • map->filter->every
  • map->filter->find
  • filter->map->some
  • filter->map->every
  • filter->map->reject->find

์ง€์—ฐ ํ‰๊ฐ€๋ฅผ ์‹œ์ž‘์‹œํ‚ค๊ณ  ์œ ์ง€ ์‹œํ‚ค๋Š” ํ•จ์ˆ˜๋Š” map, filter, reject์ด๊ณ  ๋์„ ๋‚ด๋Š” ํ•จ์ˆ˜๋Š” take, some, every, find, ์ž…๋‹ˆ๋‹ค.

users = [
  { 'id': 1, 'name': 'ID', 'age': 12 },
  { 'id': 2, 'name': 'BJ', 'age': 28 },
  { 'id': 3, 'name': 'HA', 'age': 13 },
  { 'id': 4, 'name': 'PJ', 'age': 23 },
  { 'id': 5, 'name': 'JE', 'age': 29 },
  { 'id': 6, 'name': 'JM', 'age': 32 },
  { 'id': 7, 'name': 'JE', 'age': 31 },
  { 'id': 8, 'name': 'HI', 'age': 15 },
  { 'id': 9, 'name': 'HO', 'age': 28 },
  { 'id': 10, 'name': 'KO', 'age': 34 }
]

# 10๋Œ€ 2๋ช…๊นŒ์ง€๋งŒ ์ฐพ์•„๋‚ด๊ธฐ
_.go(users,
  L.filter(lambda user, *r : user['age'] < 20),
  L.take(2),
  print)
# [{ 'id': 1, 'name': 'ID', 'age': 12 }, { 'id': 3, 'name': 'HA', 'age': 13 }]
# 3๋ฒˆ๋งŒ ๋ฐ˜๋ณต

# 10๋Œ€ 2๋ช…๊นŒ์ง€๋งŒ ์ฐพ์•„๋‚ด์„œ ์ด๋ฆ„ ์ˆ˜์ง‘ํ•˜๊ธฐ
_.go(users,
  L.filter(lambda user, *r : user['age'] < 20),
  L.map(lambda v, *r : v['name']),
  L.take(2),
  print)
# ['ID', 'HA']
# 3๋ฒˆ๋งŒ ๋ฐ˜๋ณต

L.strict

L.strict๋ฅผ ์ด์šฉํ•˜์—ฌ ์ง€์—ฐ ํ‰๊ฐ€๋ฅผ ๋™์ž‘์‹œํ‚ฌ ๊ฒƒ์ธ๊ฐ€๋ฅผ ๋™์ ์œผ๋กœ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ˆซ์ž๋กœ ํ•˜๊ธฐ:
strict_or_lazy1 = __(
  _.range,
  L.strict(100),
  L.map(lambda v, *r: v * v),
  L.filter(lambda v, *r: _.bool(v % 2)),
  L.take(10),
  print)

strict_or_lazy1(50)
# [1, 9, 25, 49, 81, 121, 169, 225, 289, 361]
# 50 ๋ฒˆ ๋ฐ˜๋ณต (์—ผ๊ฒฉ)

strict_or_lazy1(100)
# [1, 9, 25, 49, 81, 121, 169, 225, 289, 361]
# 20 ๋ฒˆ ๋ฐ˜๋ณต (์ง€์—ฐ)

strict_or_lazy1(15)
# [1, 9, 25, 49, 81, 121, 169]
# 15 ๋ฒˆ ๋ฐ˜๋ณต (์—„๊ฒฉ)
ํ•จ์ˆ˜๋กœ ํ•˜๊ธฐ:
strict_or_lazy2 = __(
  _.range,
  L.strict(lambda list, *r : len(list) < 100),
  L.map(lambda v, *r : v * v),
  L.filter(lambda v, *r : bool(v % 2)),
  L.take(10),
  print)

strict_or_lazy2(50)
# [1, 9, 25, 49, 81, 121, 169, 225, 289, 361]
# 50 ๋ฒˆ ๋ฐ˜๋ณต (์—ผ๊ฒฉ)

strict_or_lazy2(100)
# [1, 9, 25, 49, 81, 121, 169, 225, 289, 361]
# 20 ๋ฒˆ ๋ฐ˜๋ณต (์ง€์—ฐ)

strict_or_lazy2(15)
# [1, 9, 25, 49, 81, 121, 169]
# 15 ๋ฒˆ ๋ฐ˜๋ณต (์—„๊ฒฉ)