A A
[Data Mining] Crash_Course in Python Part.2

The Not-So-Basics

Sorting

x = [4,1,2,3]
y = sorted(x)    # is [1,2,3,4], x is unchanged
x.sort()         # now x is [1,2,3,4]
# sort the list by absolute value from largest to smallest
x = sorted([-4,1,-2,3], key=abs, reverse=True) # is [-4,3,-2,1]
# sort the words and counts from highest count to lowest
wc = sorted(word_counts.items(),
            key=lambda x: x[1], # x[1] ๋‘๋ฒˆ์งธ ๊ฐ’์„ ๊ธฐ์ค€์œผ๋กœ ์ •๋ ฌ
            reverse=True)

wc
# [('I', 2), ('am', 1), ('a', 1), ('boy', 1), ('love', 1), ('you', 1)]
  • x ๋ฆฌ์ŠคํŠธ๋Š” ์ ˆ๋Œ“๊ฐ’์— ๋”ฐ๋ผ ๋‚ด๋ฆผ์ฐจ์ˆœ์œผ๋กœ ์ •๋ ฌ๋ฉ๋‹ˆ๋‹ค.
    • sorted() ํ•จ์ˆ˜๋Š” ์ž…๋ ฅ ๋ฆฌ์ŠคํŠธ๋ฅผ ์ •๋ ฌํ•ฉ๋‹ˆ๋‹ค.
    • key=abs ์ธ์ž๋Š” ์ •๋ ฌ ํ‚ค๋ฅผ ์ ˆ๋Œ“๊ฐ’์œผ๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
    • reverse=True ์ธ์ž๋Š” ๋‚ด๋ฆผ์ฐจ์ˆœ์œผ๋กœ ์ •๋ ฌ๋จ์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.
  • wc๋Š” ๋‹จ์–ด ๋ฐ ํ•ด๋‹น ์นด์šดํŠธ๋ฅผ ๊ฐ€์ง„ ๋”•์…”๋„ˆ๋ฆฌ๋ฅผ ๊ฐ€์žฅ ๋งŽ์€ ์นด์šดํŠธ๋ถ€ํ„ฐ ๊ฐ€์žฅ ์ ์€ ์นด์šดํŠธ๋กœ ์ •๋ ฌ๋ฉ๋‹ˆ๋‹ค.
    • sorted() ํ•จ์ˆ˜์˜ key ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ๊ฐ ์š”์†Œ์— ๋Œ€ํ•ด ์ ์šฉ๋˜๋Š” ํ•จ์ˆ˜๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.
    • ์—ฌ๊ธฐ์„œ๋Š” ๋žŒ๋‹ค ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์š”์†Œ์˜ ๋‘ ๋ฒˆ์งธ ๊ฐ’(์นด์šดํŠธ), ๋‹จ์–ด์˜ ์ถœ์—ฐ ๋นˆ๋„๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์ •๋ ฌํ•ฉ๋‹ˆ๋‹ค.
    • reverse=True ์ธ์ž๋Š” ๋‚ด๋ฆผ์ฐจ์ˆœ์œผ๋กœ ์ •๋ ฌ๋จ์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.
word_counts.items()๋Š” ๋”•์…”๋„ˆ๋ฆฌ์˜ ๊ฐ ํ•ญ๋ชฉ์„ ํŠœํ”Œ๋กœ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด, { 'I': 2, 'am': 1, 'a': 1 }์ด๋ผ๋Š” ๋”•์…”๋„ˆ๋ฆฌ๊ฐ€ ์žˆ๋‹ค๋ฉด, items() ๋ฉ”์†Œ๋“œ๋Š” ('I', 2), ('am', 1), ('a', 1)๊ณผ ๊ฐ™์€ ํŠœํ”Œ๋“ค์˜ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
sorted() ํ•จ์ˆ˜์— ์˜ํ•ด ๋‘ ๋ฒˆ์งธ ์š”์†Œ(์ฆ‰, ํŠœํ”Œ์˜ ๋‘ ๋ฒˆ์งธ ๊ฐ’)๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๋‚ด๋ฆผ์ฐจ์ˆœ์œผ๋กœ ์ •๋ ฌ๋ฉ๋‹ˆ๋‹ค.
๋”ฐ๋ผ์„œ word_counts.items()๊ฐ€ ํŠœํ”Œ๋“ค์˜ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฏ€๋กœ ๋‘ ๋ฒˆ์งธ ๊ฐ’์€ ํ•ด๋‹น ๋‹จ์–ด์˜ ์ถœํ˜„ ๋นˆ๋„๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.
x[0]: โ€˜๋‹จ์–ดโ€™, x[1]: โ€˜์ˆซ์žโ€™
  • ๋‹จ์–ด์™€ ํ•ด๋‹น ์นด์šดํŠธ๋ฅผ ๊ฐ€์žฅ ๋งŽ์€ ์นด์šดํŠธ๋ถ€ํ„ฐ ๊ฐ€์žฅ ์ ์€ ์นด์šดํŠธ๋กœ ์ •๋ ฌํ•ฉ๋‹ˆ๋‹ค.

List Comprehensions

  • ํŠน์ • ์š”์†Œ๋งŒ์„ ์„ ํƒํ•˜๊ฑฐ๋‚˜ ์š”์†Œ๋ฅผ ๋ณ€ํ™˜ํ•˜๊ฑฐ๋‚˜ ๋‘˜ ๋‹ค๋ฅผ ์„ ํƒํ•˜์—ฌ ๋ชฉ๋ก์„ ๋‹ค๋ฅธ ๋ชฉ๋ก์œผ๋กœ ๋ณ€ํ™˜ํ•˜๊ณ ์ž ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.
  • ๋ชฉ๋ก์˜ ํฌ๊ด„์„ฑ์€ ํŒŒ์ดํ† ๋‹‰ ๋ฐฉ์‹์— ์˜ํ•ด ๊ฒฐ์ •๋ฉ๋‹ˆ๋‹ค.
  • ๊ฐ€๋Šฅํ•˜๋ฉด ํ•ญ์ƒ List Comprehensions๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
even_numbers = [x for x in range(5) if x % 2 == 0]  # [0, 2, 4], 0 ~ 4 ์‚ฌ์ด์ค‘
squares      = [x * x for x in range(5)]            # [0, 1, 4, 9, 16]
even_squares = [x * x for x in even_numbers]        # [0, 4, 16]
  • ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ List์„ Dictionary ๋˜๋Š” Set์œผ๋กœ ๋ณ€ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
square_dict = { x : x * x for x in range(5) }  # { 0:0, 1:1, 2:4, 3:9, 4:16 }
square_set = { x * x for x in [1, -1] }        # { 1 } # set์€ ์ค‘๋ณต ์š”์†Œ ํฌํ•จ X
  • ๋ณ€์ˆ˜๋กœ ๋ฐ‘์ค„์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ผ๋ฐ˜์ ์ž…๋‹ˆ๋‹ค.
    • โ€˜_โ€™์€ ๊ฐ’์ด ํ•„์š”ํ•˜์ง€ ์•Š์„๋•Œ ์‚ฌ์šฉ. even_numbers = [0, 2, 4] โ†’ Zeros List: [0, 0, 0]'
zeroes = [0 for _ in even_numbers]    # has the same length as even_numbers
  • List Comprehension ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ์ด์œ ๊ฐ€ ํฌํ•จ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
pairs = [(x, y)
         for x in range(10)
         for y in range(10)] # 100 pairs (0,0) (0,1) ... (9,8), (9,9)
  • ์ปดํ“จํ„ฐ ์‚ฌ์šฉ์ด ์‰ฌ์šด ๊ฑฐ๋ฆฌ ํ–‰๋ ฌ, ๋‚˜์ค‘์—๋Š” ์ด์ „์˜ ๊ฒฐ๊ณผ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
increasing_pairs = [(x, y)
                    for x in range(10)
                    for y in range(x + 1, 10)]
                    
# [(0,1), (0,2), (0,3) ... (8, 9)]
  • 0๋ถ€ํ„ฐ 9๊นŒ์ง€์ธ ๋ชจ๋“  ์ˆซ์ž ์Œ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  • ์ด ์Œ๋“ค์€ ์ฒซ ๋ฒˆ์งธ ์š”์†Œ๊ฐ€ ๋‘ ๋ฒˆ์งธ ์š”์†Œ๋ณด๋‹ค ์ž‘์€ ์ฆ๊ฐ€ํ•˜๋Š” ์ˆœ์„œ์Œ์ž…๋‹ˆ๋‹ค.

Generators & Iterators

  • List์˜ ๋ฌธ์ œ์ ์€ List๊ฐ€ ์‰ฝ๊ฒŒ ๋งค์šฐ ์ปค์งˆ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
  • range(1000000)๋Š” ์‹ค์ œ 100๋งŒ ๊ฐœ์˜ ์›์†Œ ๋ชฉ๋ก์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
  • ๋งŒ์•ฝ ๋‹น์‹ ์ด ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์”ฉ๋งŒ ๋‹ค๋ฃจ๋ฉด ๋œ๋‹ค๋ฉด, ์ด๊ฒƒ์€ ์—„์ฒญ๋‚œ ๋น„ํšจ์œจ์„ฑ์˜ ์›์ฒœ(๋˜๋Š” ๋ฉ”๋ชจ๋ฆฌ ๋ถ€์กฑ์˜ ์›์ธ)์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๋งŒ์•ฝ ๋‹น์‹ ์ด ์ž ์žฌ์ ์œผ๋กœ ์ฒ˜์Œ ๋ช‡ ๊ฐœ์˜ ๊ฐ’๋งŒ ํ•„์š”ํ•˜๋‹ค๋ฉด, ๊ทธ๊ฒƒ๋“ค์„ ๋ชจ๋‘ ๊ณ„์‚ฐํ•˜๋Š” ๊ฒƒ์€ ๋‚ญ๋น„์ž…๋‹ˆ๋‹ค.
  • Generator๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ๋ฐ˜๋ณตํ•  ์ˆ˜ ์žˆ์ง€๋งŒ(์šฐ๋ฆฌ์˜ ๊ฒฝ์šฐ, ์ผ๋ฐ˜์ ์œผ๋กœ ์— ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค) ํ•„์š”์— ๋”ฐ๋ผ ๊ฐ’์ด ์ƒ์„ฑ๋˜๋Š” ๊ฒƒ(lazily)์ž…๋‹ˆ๋‹ค.
  • Generator๋ฅผ ๋งŒ๋“œ๋Š” ํ•œ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์€ ํ•จ์ˆ˜์™€ yield ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค:
def lazy_range(n):
    """a lazy version of range"""
    i = 0
    while i < n:
        yield i
        i += 1
# The following loop will consume the yield ed values one at a time until none are left:
for i in lazy_range(10):
    print(i)
0
1
2
3
4
5
6
7
8
9
# The following loop will consume the yield ed values one at a time until none are left:
for i in lazy_range(10000):
    if i == 3: break
    print(i)
0
1
2
t = lazy_range(3)
next(t)
next(t)
next(t)
#next(t)

# 2
def lazy_inf_range():
    i = 0
    while True:
        yield i
        i += 1

t = lazy_inf_range()
next(t)
next(t)
next(t)

# 2
  • Generator๋ฅผ ๋งŒ๋“œ๋Š” ๋‘ ๋ฒˆ์งธ ๋ฐฉ๋ฒ•์€ ๊ด„ํ˜ธ ์•ˆ์œผ๋กœ ํฌ์žฅ๋œ comprehension์— ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค:
lazy_evens_below_20 = (i for i in lazy_range(20) if i % 2 == 0)
lazy_evens_below_20

# <generator object <genexpr> at 0x7cce6849c4a0>

Randomness

  • ๋‚œ์ˆ˜๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•ด, ์šฐ๋ฆฌ๋Š” ๋‚œ์ˆ˜ ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • random.random()๋Š” 0์—์„œ 1 ์‚ฌ์ด์˜ ์ˆซ์ž๋ฅผ ๊ท ์ผํ•˜๊ฒŒ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
import random

four_uniform_randoms = [random.random() for _ in range(4)]
four_uniform_randoms
[0.15001730378211198,
 0.047689363188983425,
 0.4438845111618783,
 0.8064273339306516]
  • reproducible ๊ฐ€๋Šฅํ•œ ๊ฒฐ๊ณผ๋ฅผ ์–ป์œผ๋ ค๋Š” ๊ฒฝ์šฐ.
random.seed(10)
print(random.random())
random.seed(10)
print(random.random())
0.5714025946899135
0.5714025946899135
  • random.randrange๋Š” 1 ๋˜๋Š” 2๊ฐœ์˜ ์ธ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ํ•ด๋‹น ๋ฒ”์œ„ ()์—์„œ ์ž„์˜๋กœ ์„ ํƒํ•œ ์š”์†Œ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
random.randrange(10)      # choose randomly from range(10) = [0, 1, ..., 9]
random.randrange(3, 6)    # choose randomly from range(3, 6) = [3, 4, 5]
  • random.shuffle๋Š” ๋ชฉ๋ก์˜ ์š”์†Œ๋ฅผ ์ž„์˜๋กœ ์žฌ์ •๋ ฌํ•ฉ๋‹ˆ๋‹ค:
up_to_ten = list(range(10))
random.shuffle(up_to_ten)
print(up_to_ten)

# 4, 5, 8, 1, 2, 6, 7, 3, 0, 9]
  • ๋ชฉ๋ก์—์„œ ํ•œ ์š”์†Œ๋ฅผ ์ž„์˜๋กœ ์„ ํƒํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.
my_best_friend = random.choice(["Alice", "Bob", "Charlie"])
  • ๋Œ€์ฒดํ•˜์ง€ ์•Š๊ณ  ์›์†Œ ํ‘œ๋ณธ์„ ์ž„์˜๋กœ ์„ ํƒํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. (์ฆ‰, ์ค‘๋ณต๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค)
lottery_numbers = range(60)
winning_numbers = random.sample(lottery_numbers, 6)
  • ๋Œ€์ฒด ์š”์†Œ ํ‘œ๋ณธ์„ ์„ ํƒํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.(์ฆ‰, ์ค‘๋ณต์„ ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค)
four_with_replacement = [random.choice(range(10)) for _ in range(4)]
four_with_replacement

# [2, 9, 5, 6]
  • random.choice(range(10))๋Š” 0๋ถ€ํ„ฐ 9๊นŒ์ง€์˜ ์ˆซ์ž ์ค‘์—์„œ ํ•˜๋‚˜๋ฅผ ๋ฌด์ž‘์œ„๋กœ ์„ ํƒํ•˜๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.
  • ์ด๋ฅผ ๋ฆฌ์ŠคํŠธ ์ปดํ”„๋ฆฌํ—จ์…˜ ์œผ๋กœ 4๋ฒˆ ๋ฐ˜๋ณตํ•˜์—ฌ ๋ฆฌ์ŠคํŠธ๋ฅผ ์ƒ์„ฑ. ์ค‘๋ณต์„ ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋ฌด์ž‘์œ„๋กœ ์„ ํƒ๋œ 0๋ถ€ํ„ฐ 9๊นŒ์ง€์˜ ์ˆซ์ž๊ฐ€ 4๊ฐœ ํฌํ•จ.

Regular Expressions

  • ์ •๊ทœ ํ‘œํ˜„์‹์€ ํ…์ŠคํŠธ๋ฅผ ๊ฒ€์ƒ‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
  • ๊ทธ๊ฒƒ๋“ค์€ ๋ฏฟ์„ ์ˆ˜ ์—†์„ ์ •๋„๋กœ ์œ ์šฉํ•˜์ง€๋งŒ ๋˜ํ•œ ๊ฝค ๋ณต์žกํ•ด์„œ ๊ทธ๊ฒƒ๋“ค์— ๋Œ€ํ•œ ์ „์ฒด ์ฑ…์ด ์žˆ์Šต๋‹ˆ๋‹ค.
import re

# ์ •๊ทœ ํ‘œํ˜„์‹์„ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค์–‘ํ•œ ๋ฌธ์ž์—ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ณ , ๊ฐ ์ž‘์—…์˜ ๊ฒฐ๊ณผ๋ฅผ ๊ฒ€์‚ฌํ•ฉ๋‹ˆ๋‹ค.
# ๋ชจ๋“  ์กฐ๊ฑด์ด ์ฐธ์ผ ๊ฒฝ์šฐ True๋ฅผ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.

print(all([
    not re.match("a", "cat"),                # "cat" ๋ฌธ์ž์—ด์€ "a"๋กœ ์‹œ์ž‘ํ•˜์ง€ ์•Š์Œ
    re.search("a", "cat"),                    # "cat" ๋ฌธ์ž์—ด์— "a"๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Œ
    not re.search("c", "dog"),                # "dog" ๋ฌธ์ž์—ด์— "c"๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์ง€ ์•Š์Œ
    3 == len(re.split("[ab]", "carbs")),    # "carbs" ๋ฌธ์ž์—ด์„ "[ab]"๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๋ถ„ํ• ํ•˜๋ฉด ['c', 'r', 's']๊ฐ€ ๋˜๋ฉฐ, ๊ธธ์ด๊ฐ€ 3์ž„
    "R-D-" == re.sub("[0-9]", "-", "R2D2")    # "R2D2" ๋ฌธ์ž์—ด์—์„œ ์ˆซ์ž๋ฅผ "-"๋กœ ๋Œ€์ฒดํ•˜๋ฉด "R-D-"๊ฐ€ ๋จ
]))    # ์ถœ๋ ฅ ๊ฒฐ๊ณผ๋Š” True


Object-Oriented Programming

# ๊ด€๋ก€์ ์œผ๋กœ, ํด๋ž˜์Šค๋Š” PascalCase ์ด๋ฆ„์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
class Set:
    # ์ด๊ฒƒ๋“ค์€ ๋ฉค๋ฒ„ ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.
    # ๊ฐ ํ•จ์ˆ˜๋Š” "self"๋ผ๋Š” ์ฒซ ๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๊ฐ€์ ธ์•ผ ํ•ฉ๋‹ˆ๋‹ค(๋˜ ๋‹ค๋ฅธ ๊ด€๋ก€์ž…๋‹ˆ๋‹ค).
    # ์ด "self"๋Š” ์‚ฌ์šฉ๋˜๋Š” ํŠน์ • Set ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚ต๋‹ˆ๋‹ค.

    def __init__(self, values=None):
        """์ด๊ฒƒ์€ ์ƒ์„ฑ์ž์ž…๋‹ˆ๋‹ค.
        ์ƒˆ๋กœ์šด Set์„ ๋งŒ๋“ค ๋•Œ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.
        ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
        s1 = Set()          # ๋นˆ ์ง‘ํ•ฉ
        s2 = Set([1,2,2,3]) # ๊ฐ’์œผ๋กœ ์ดˆ๊ธฐํ™”"""

        self.dict = {}  # ๊ฐ Set ์ธ์Šคํ„ด์Šค๋งˆ๋‹ค ๊ณ ์œ ํ•œ dict ์†์„ฑ์ด ์žˆ์Šต๋‹ˆ๋‹ค.
                        # ์ด ์†์„ฑ์€ ๋ฉค๋ฒ„์‹ญ์„ ์ถ”์ ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
        if values is not None:
            for value in values:
                self.add(value)

    def __repr__(self):
        """์ด๊ฒƒ์€ Set ๊ฐ์ฒด์˜ ๋ฌธ์ž์—ด ํ‘œํ˜„์ž…๋‹ˆ๋‹ค.
        Python ํ”„๋กฌํ”„ํŠธ์—์„œ ์ž…๋ ฅํ•˜๊ฑฐ๋‚˜ str()์— ์ „๋‹ฌํ•˜๋ฉด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค."""
        return "Set: " + str(self.dict.keys())

    # ๊ฐ ์š”์†Œ์˜ ๋ฉค๋ฒ„์‹ญ์€ self.dict์˜ ํ‚ค๋กœ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.
    def add(self, value):
        self.dict[value] = True

    # ๊ฐ’์ด ์ง‘ํ•ฉ์— ์žˆ๋Š”์ง€ ์—ฌ๋ถ€๋Š” ์‚ฌ์ „์˜ ํ‚ค๋กœ ํŒ๋ณ„๋ฉ๋‹ˆ๋‹ค.
    def contains(self, value):
        return value in self.dict

    def remove(self, value):
        del self.dict[value]

s = Set([1,2,3])
s.add(4)
print(s.contains(4))    # True
s.remove(3)
print(s.contains(3))    # False

Function Tools

  • ํ•จ์ˆ˜๋ฅผ ์ „๋‹ฌํ•  ๋•Œ ์ƒˆ ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ๋ถ€๋ถ„์ ์œผ๋กœ (๋˜๋Š” ์นด๋ ˆ) ํ•จ์ˆ˜๋ฅผ ์ ์šฉํ•˜๊ณ  ์‹ถ์„ ๋•Œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค
def exp(base, power):
    return base ** power

def two_to_the(power):
    return exp(2, power)
    
two_to_the(3)

# 8
  • functools.partial์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ๋‹ค๋ฅธ ์ ‘๊ทผ ๋ฐฉ์‹
from functools import partial

two_to_the = partial(exp, 2)     # is now a function of one variable
print(two_to_the(3))             # 8

square_of = partial(exp, power=2)
print(square_of(3))    # 9
  • ๋˜ํ•œ map, reduce ๋ฐ filter๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ดํ•ด๋ฅผ ๋‚˜์—ดํ•˜๋Š” ๊ธฐ๋Šฅ์  ๋Œ€์•ˆ์„ ์ œ๊ณตํ•˜๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค:
  • ํ•ญ์ƒ map ์‚ฌ์šฉํ•˜๊ณ  ๊ฐ€๋Šฅํ•˜๋ฉด reduceํ•˜๊ณ  filteringํ•ฉ๋‹ˆ๋‹ค.

Map

def double(x):
    return 2 * x

xs = [1, 2, 3, 4]

# ๋ฆฌ์ŠคํŠธ ์ปดํ”„๋ฆฌํ—จ์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ ์š”์†Œ๋ฅผ ๋‘ ๋ฐฐ๋กœ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
twice_xs = [double(x) for x in xs]

# map ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ ์š”์†Œ๋ฅผ ๋‘ ๋ฐฐ๋กœ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
twice_xs = map(double, xs)

# partial ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ map ํ•จ์ˆ˜์— double ํ•จ์ˆ˜๋ฅผ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.
list_doubler = partial(map, double)
# list_doubler๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ xs์˜ ๊ฐ ์š”์†Œ๋ฅผ ๋‘ ๋ฐฐ๋กœ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
twice_xs = list_doubler(xs)

def multiply(x, y): return x * y

products = map(multiply, [1, 2], [4, 5])    # [1 * 4, 2 * 5] = [4, 10]
list(products)

# [4,10]
def multiply(x, y, z): return x * y * z

products = map(multiply, [1, 2], [4, 5], [10, 20])    # [1 * 4 * 10, 2 * 5 * 20]
list(products)

# [40, 200]

Filter

def is_even(x):
    """x๊ฐ€ ์ง์ˆ˜์ด๋ฉด True, ํ™€์ˆ˜์ด๋ฉด False๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค."""
    return x % 2 == 0

xs = [1, 2, 3, 4]

# ๋ฆฌ์ŠคํŠธ ์ปดํ”„๋ฆฌํ—จ์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ ์ง์ˆ˜๋งŒ ํ•„ํ„ฐ๋งํ•ฉ๋‹ˆ๋‹ค.
x_evens = [x for x in xs if is_even(x)]
print(x_evens)

# filter ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ง์ˆ˜๋งŒ ํ•„ํ„ฐ๋งํ•ฉ๋‹ˆ๋‹ค.
x_evens = filter(is_even, xs)
print(list(x_evens))

# partial ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ filter ํ•จ์ˆ˜์— is_even ํ•จ์ˆ˜๋ฅผ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.
list_evener = partial(filter, is_even)
# list_evener๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ xs์—์„œ ์ง์ˆ˜๋งŒ ํ•„ํ„ฐ๋งํ•ฉ๋‹ˆ๋‹ค.
x_evens = list_evener(xs)
print(list(x_evens))
[2, 4]
[2, 4]

Reduce

def multiply(x, y): return x * y

xs = [1,2,3]
x_product = reduce(multiply, xs)
print(x_product)
list_product = partial(reduce, multiply)
x_product = list_product(xs)
print(x_product)
6
6

Enumerate

  • ๋ชฉ๋ก์—์„œ ๋ฐ˜๋ณตํ•˜๊ณ  ํ•ด๋‹น ์š”์†Œ์™€ ์ธ๋ฑ์Šค๋ฅผ ๋ชจ๋‘ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.
documents = ["I", "am", "a", "boy"]
# not Pythonic
for i in range(len(documents)):
    document = documents[i]
    print(i, document)

# also not Pythonic
i = 0
for document in documents:
    print(i, document)
    i += 1
0 I
1 am
2 a
3 boy
0 I
1 am
2 a
3 boy
  • Pythonic solution์€ ์—ด๊ฑฐํ˜•์œผ๋กœ ํŠœํ”Œ(์ธ๋ฑ์Šค, ์š”์†Œ)์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค:
for i, document in enumerate(documents):
    print(i, document)
0 I
1 am
2 a
3 boy
for i in range(len(documents)): print(i)    # not Pythonic

for i, _ in enumerate(documents): print(i)  # Pythonic
0
1
2
3
0
1
2
3

Zip & Unzip

  • ๋‘˜ ์ด์ƒ์˜ ๋ชฉ๋ก์„ ํ•จ๊ป˜ ์••์ถ•ํ•ฉ๋‹ˆ๋‹ค.
  • zip์€ ์—ฌ๋Ÿฌ ๋ชฉ๋ก์„ ํ•ด๋‹น ์š”์†Œ์˜ ํŠœํ”Œ ๋‹จ์ผ ๋ชฉ๋ก์œผ๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค:
list1 = ['a', 'b', 'c']
list2 = [1, 2, 3]
list(zip(list1, list2))        # is [('a', 1), ('b', 2), ('c', 3)]
  • ์ด์ƒํ•œ ์†์ž„์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ List๋ฅผ "Unzip"ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค:
pairs = [('a', 1), ('b', 2), ('c', 3)]
letters, numbers = zip(*pairs)
print(letters, numbers)

# ('a', 'b', 'c') (1, 2, 3)
pairs = [('a', 1), ('b', 2), ('c', 3)]
letters, numbers = zip(('a', 1), ('b', 2), ('c', 3))
print(letters, numbers)

# ('a', 'b', 'c') (1, 2, 3)