특성
1. def 키워드를 사용해서 정의한다.
2. 리턴 타입에 대한 정의가 필요없다.
3. return 이 없으면 None을 반환한다.
# return true if any number is even inside a list
# 리스트 안에 짝수가 하나라도 있으면 True, 하나도 없으면 False 반환
def check_even_list(nums):
for n in nums:
if n % 2 == 0:
return True
else:
pass
return False
# 초보자들은 else 문이 if와 짝을 이루어야 한다고 생각하지만
# logic을 잘 생각해 보면 그렇지 않음을 알 수 있다.
# 모든 리턴 값이 들여쓰기 될 필요는 없다.
print(f'[1, 3, 5] -> {check_even_list([1, 3, 5])}')
print(f'[1, 2, 5] -> {check_even_list([1, 2, 5])}')
print(f'[1, 5, 2] -> {check_even_list([1, 5, 2])}')
# 결과
[1, 3, 5] -> False
[1, 2, 5] -> True
[1, 5, 2] -> True
# 3개의 임의 리스트 중 하나를 선택해 맞췄는지 판단
# 함수를 여러 개 만들고 그들을 하나로 상호작용하게 한다.
# game_list = [' ', 'O', ' ']
from random import shuffle
# 1) shuffle 함수는 아무것도 반환하지 않는다.
# 2) 따라서, init_guess가 변경되어 반환하지 않아도 된다.
# 3) 그러나, 명시적인 반환으로 구현하는게 명확하다.
def shuffle_list(init_guess):
shuffle(init_guess)
return init_guess
def player_guess():
guess = ''
while guess not in ['0', '1', '2']:
guess = input('Pick a number: 0, 1 or 2')
return int(guess)
def check_guess(mixed_list, guess_idx):
if mixed_list[guess_idx] == 'O':
print('Correct!')
else:
print('Wrong guess!')
print(mixed_list)
init_guess = [' ', 'O', ' ']
mixed_list = shuffle_list(init_guess)
player_guess = player_guess()
check_guess(mixed_list, player_guess)
# 결과
Pick a number: 0, 1 or 21
Wrong guess!
[' ', ' ', 'O']
## 숫자를 받아 그것이 모두 짝수이면 그중 작은 수를 반환
## 숫자중 홀수가 포함되면 그중 큰 수를 반환
## 쉬운 구현
def lesser_of_two_evens(num1, num2):
if num1 % 2 == 0 and num2 % 2 == 0:
return min(num1, num2)
else:
return max(num1, num2)
print(lesser_of_two_evens(2, 4))
print(lesser_of_two_evens(1, 2))
# 결과
2
2
## 나의 솔루션
def my_lesser_of_two_evens(*args):
is_all_even = False
for n in args:
if n % 2 == 0:
is_all_even = True
else:
is_all_even = False
break
if is_all_even:
return min(args)
else:
return max(args)
print(my_lesser_of_two_evens(2, 4))
print(my_lesser_of_two_evens(1, 2))
print(my_lesser_of_two_evens(1, 2, 3))
# 결과
2
2
3
# PEP 8, de-facto code style guide for Python
# PEP 8에 의거 최상위 함수와 클래스는 다른 코드와 두 줄씩 띄어 쓴다.
# 클래스 내의 메서드는 한 줄씩 띄어 쓴다.
## ANIMAL CRACKERS: Write a function takes a two-word string and
## returns True if both words begin with same letter.
##
## animal_crackers('Levelheaded Llama') --> True
## animal_crackers('Crazy Kangaroo') --> False
## 솔루션 버전
def animal_cracers(strs):
word_list = strs.lower().split()
first_word = word_list[0]
second_word = word_list[1]
return first_word[0] == second_word[0]
print(animal_cracers('Levelheaded Llama'))
print(animal_cracers('Crazy Kangaroo'))
## 나의 버전
## (솔루션 버전의 해법을 보니 이런 식은 나중에 기억하기 어려워서 좋은 구현은 아니다.
def my_animal_crackers(strs):
word_list = strs.split()
if word_list[0][0] == word_list[1][0]:
return True
else:
return False
print(my_animal_crackers('Levelheaded Llama'))
print(my_animal_crackers('Crazy Kangaroo'))
# 결과
True
False
True
False
## Given a list of ints, return True if the array contains a 3 next to a 3 somewhere.
## 3 3이 연달아 존재하면 True 반환
##
## has_33([1, 3, 3) -> True
## has_33([1, 3, 1, 3]) -> False
## has_33([3, 1, 3) -> False
##
## 나는 그냥 같은 숫자가 두 번 연속으로 나오면 True로 구현했다.
def my_has_33(num_list):
for idx in range(0, len(num_list)-1):
current_num = num_list[idx]
next_num = num_list[idx + 1]
if current_num == next_num:
return True
return False
result1 = my_has_33([1, 3, 3])
result2 = my_has_33([1, 3, 1, 3])
result3 = my_has_33([3, 1, 3])
result4 = my_has_33([3, 1, 1, 1, 3])
print(result1, result2, result3, result4)
# 결과
True False False True
## SPY GAME: Write a function that takes in a list of integers and returns
## True if it contains 007 in order.
##
## 0, 0, 7이 이어지지 않아도 순서대로 존재하면 True 반환
## 7, 0, 0은 False 반환
def spy_game(nums):
code = [0, 0, 7, 'x']
# [0, 7, 'x']
# [7, 'x']
# ['x] length = 1
for n in nums:
if n == code[0]:
code.pop(0)
return len(code) == 1
result1 = spy_game([1, 2, 3, 0, 0, 7, 5])
result2 = spy_game([1, 0, 2, 4, 0, 5, 7])
result3 = spy_game([1, 7, 2, 0, 4, 5, 0])
print(result1, result2, result3)
# 결과
True True False
# 대소문자 글자수 카운트
text = 'Hello Mr. Rogers, how are you this fine Tuesday?'
def up_low(text):
uppercase, lowercase = 0, 0
for char in text:
if char.isupper():
uppercase += 1
elif char.islower():
lowercase += 1
else:
pass # is '?' is entered.
return (uppercase, lowercase)
print(f'Original String: {text}')
print(f'No. of Upper case characters: {up_low(text)[0]}')
print(f'No. of Lower case characters: {up_low(text)[1]}')
# 결과
Original String: Hello Mr. Rogers, how are you this fine Tuesday?
No. of Upper case characters: 4
No. of Lower case characters: 33
# 고유한 리스트 요소만 반환
def uniqe_list(lst):
d = dict()
for l in lst:
if d.get(l, None) == None:
d.setdefault(l, 1)
else:
d[l] += 1
return d.items()
sample_list = [1, 1, 1, 1, 2, 2, 3, 3, 3, 3, 4, 5]
print(f'Original list: {sample_list}')
print(uniqe_list((sample_list)))
# 결과
Original list: [1, 1, 1, 1, 2, 2, 3, 3, 3, 3, 4, 5]
dict_items([(1, 4), (2, 2), (3, 4), (4, 1), (5, 1)])
# 인자 (argument)와 리턴 (return)이 없는 간단한 함수의 생성
def myFunc():print('It\'s my function.')
myFunc()
결과)It's my function.
# 사용하기 전에 정의가 되어 있어야 한다.myFunc()
def myFunc():print('It\'s my function.')
결과)NameError: name 'myFunc' is not defined
# return 이 없으면 무조건 None 을 반환한다.def mySecondFunc():pass
result = mySecondFunc()print(result)
결과)None
# 함수는 return 과 함께 종료하며 return 뒤의 반환값을 호출한 곳으로 반환한다.def myThirdFunc():return True
result = myThirdFunc()print(result)
결과)True
# 함수 인자는 pass by reference로 동작함l = [1, 2, 3]
def byRefExam(lists): lists.append('4') return
byRefExam(l)
print(l)
결과)[1, 2, 3, '4']
# 기본값을 가진 인자의 사용
def useDefaultArgs(age, name = 'sally'):print(name, age)
useDefaultArgs(16)
결과)sally 16
# 기본값 인자가 순서상 가장 먼저 나오면 안 된다.
def useDefaultArgs(name = 'sally', age):print(name, age)
useDefaultArgs(16)
결과)SyntaxError: non-default argument follows default argument
# 인자가 일치하지 않으면 에러가 발생한다.def useDefaultArgs(name = 'sally'):print(name, age)
useDefaultArgs(16)
결과)NameError: name 'useDefaultArgument' is not defined
# 인자에 열거형 데이터 사용하기def useDefaultArgs(mylist):print('length: ' + str(len(mylist)))
l = ['1', '2']
useDefaultArgs(l)
결과)length: 2
# 열거형 데이터를 기본값 인자로 사용하기def addItems(items, base = []):for item in items:base.append(item)return base
addItems((1, 2, 3))result = addItems((4, 5, 6))
print(result)
결과)[1, 2, 3, 4, 5, 6]
# 인자의 유무를 None 플래그로 판단해 초기화하면 의도대로 구현할 수 있다.def addItems(items, base = None):if base is None:base = []for item in items:base.append(item)return base
addItems((1, 2, 3))result = addItems((4, 5, 6))
print(result)
결과)[4, 5, 6]
# 가변 인자의 사용def varArgs(*args):print(args)
varArgs('I am ')varArgs('I am ', ' a variable argument')
결과)('I am ',)('I am ', ' a variable argument')
# 가변 인자는 튜플로 알아서 할당된다.def listArgs(one, two, *args): print(one, two, args)
print(listArgs(1, 2, 3, 4, 5))
결과)1 2 (3, 4, 5)
# 가변인자로 할당된 튜플 꺼내쓰기def listArgs(one, two, *args):
print(one, two) for n in args: print(n)
print(listArgs(1, 2, 3, 4, 5))
결과)1 2345None
# 익명함수와 가변 인자의 사용
add2 = lambda x, y: x + y
x = [2, 3]
print(add2(*x))
결과)5# 가변 키워드 인자의 사용 #1def varArgs(**kwargs):print(kwargs)
varArgs(name = 'mike')
결과){'name': 'mike'}
# 가변 키워드 인자의 사용 #2
def keywordArgs(**kwargs): print(kwargs['one'], kwargs['two'], kwargs['three'])
keywordArgs(one = 1, two = 2, three = 3)
결과)1 2 3
# 가변 인자의 혼합 사용def mixedVarArgs(a, b, *args, **kwargs):print('a, b:' , (a, b))print('args: ' , args)print('kwargs: ' , kwargs)
mixedVarArgs(1, 2, 3, 4, e = 0, f = 99)
결과)a, b: (1, 2)args: (3, 4)kwargs: {'e': 0, 'f': 99}# 튜플 가변인자와 dict 가변 인자에 대한 보충 설명http://www.saltycrane.com/blog/2008/01/how-to-use-args-and-kwargs-in-python/
# 키워드 가변 인자의 사용
# 키워드 가변 인자는 결국 dict 인자를 받겠다는 것
def check_fruits(**kwargs):
if 'fruit' in kwargs:
print(f'My fruit of choice is {kwargs['fruit']}.')
else:
print('I did not find any fruit here.')
check_fruits(fruit = 'banana')
check_fruits(doing = 'bike')
# 여러 인자를 넣어도 하나만 처리 외부 라이브러리에 많이 사용
check_fruits(fruit = 'banana', veggie = 'sweet potato')
# 결과
My fruit of choice is banana.
I did not find any fruit here.
My fruit of choice is banana.
# 코드 경로에 따라 변수를 참조하지 못하는 경우가 발생한다.
def innerFunc(text):if text is 'x':output = 'x is here'return output
print(innerFunc('x'))print(innerFunc('y'))
결과)x is hereUnboundLocalError: local variable 'output' referenced before assignment
# 함수를 리스트에 넣고 호출하기def fa():print('function a.')
def fb():print('function b.')
l = [fa, fb]
l[0]()l[1]()
결과)function a.function b.
# 함수를 튜플에 넣고 호출하기def fa():print('function a.')
def fb():print('function b.')
l = (fa, fb)
l[0]()l[1]()
결과)function a.function b.
# 함수를 사전에 넣고 호출하기 #1def fa():print('function a.')
def fb():print('function b.')
d = {'first':fa, 'second':fb}
for k, v in d.items():v()
결과)function b.function a. # 순서 유지는 안 된다.
# 함수를 사전에 넣고 호출하기 #2
def fa():print('function a.')
def fb():print('function b.')
d = {0:fa, 1:fb} # key에 정수를 직접 넣을 수도 있다.
for i in range(0, len(d), 1):d[i]()
결과)function a.function b. # 순서를 가지는 정수를 발생시켜서 키로 쓰기 때문에 순서가 유지된다.
# 재귀함수의 활용예 1
def explode(word): if len(word) <= 1: return word else: return word[0] + ' ' + explode(word[1:])
print(explode('hello'))
결과)h e l l o
# 재귀함수의 활용예 2
def removeDups(word): if len(word) <= 1: return word elif word[0] == word[1]: return removeDups(word[1:]) else: return word[0] + removeDups(word[1:])
print(removeDups('aabbbc'))
결과)abc
# 함수를 중첩하면 보다 간단한 로직을 만들 수 있다.def plusDouble(f, s): def Double(n): return n * n return Double(f) + Double(s)
print(plusDouble(1, 2))
결과)5
# 두 함수의 결과를 한 번에 리턴할 수 있으며 분리된 함수를 한 곳에 모을 수 있다.def displayFE(s): def First(s): return s[0:1] def End(s): return s[-1:] return First(s) + End(s)
print(displayFE('masterpiece'))
결과)me
# 함수를 변수에 할당할 수 있는 성질을 이용한 중첩 함수의 이용def create_adder(first): def add(first, second): return first + second def adder(second): return add(first, second) return adder
addTo2 = create_adder(2)
print(addTo2(3))
결과)5
# 람다함수를 이용해서 두 함수의 결과를 합칠 수 있다.def displayFE(s): x = (lambda s: s[0:1])(s) y = (lambda s: s[-1:])(s) return x + y
print(displayFE('masterpiece'))
결과)me
# 익명 함수를 사용할 수 있다.
l = [5, 10, 20]result = filter(lambda x : x > 5, l)print(list(result))
결과)[10, 20]
# 함수 자체를 변수에 저장할 수 있어서 람다함수와 결합할 수 있다.
sq = lambda x: x*x
print(sq(2))
결과)4
# 람다함수는 함수 객체를 생성하기 때문에 그 자체로도 map 함수의 인자가 될 수 있다.sq = lambda x: x*x
print(list(map(sq, [1, 2, 3])))
결과)[1, 4, 9]
# 람다함수를 실행하면 함수 객체만 반환한다.print(lambda n : n * 2)
결과)<function <lambda> at 0x000000000203CBF8>
# 함수를 변수에 저장하지 않고도 인자를 전달할 수 있다.print((lambda n : n * n)(2))
결과)4
# 람다함수는 함수이므로 인자를 주어 호출해야 결과를 얻을 수 있다.l = ['Oh', 'My', 'God']
a = lambda x: [c[0] for c in x]
print(''.join(a(l)))
결과)OMG
# map() 내장함수를 이용한 첫글자 추출l = ['Oh', 'My', 'God']
a = lambda x: x[0]
print(list(map(a, l)))
결과)['O', 'M', 'G']
# 시퀸스 형을 람다함수에 인자로 주어야 할때는 map 함수를 사용한다. map 함수는 개별 시퀀스 형 데이터에 대해서 각각 어떤 처리를 할 때 사용한다.print(list(map(lambda n: n+1, [1, 2, 3])))
결과)[2, 3, 4]
# 축약어 만들기 - map과 lambda 함수 사용words = ['as', 'soon', 'as', 'possible']
print(''.join(map(lambda s: s[0].upper(), words)))
결과)ASAP
# 축약어 만들기 - 시퀀스 순회로 스트링 조합
words = ['as', 'soon', 'as', 'possible']result = ''for w in words: result += w[0].upper()print(result)
결과)ASAP
# 축약어 만들기 - 리스트 컴프리헨션 사용
words = ['as', 'soon', 'as', 'possible']
print(''.join([x[0].upper() for x in words]))
결과)ASAP
# 시퀀스 형 데이터를 누적식으로 처리할 때는 functools 모듈의 reduce() 함수를 사용한다.import functools
n = range(1, 11)sum = functools.reduce(lambda x, y: x+y, n)print(sum)
결과)55
# Flatten a listimport functools
words = ['this', 'is', 'a', 'new', 'world']print(functools.reduce(str.__add__, words))
결과)thisisanewworld
#시퀀스 타입이 스트링일 때 처리
import functools
words = ['this', 'is', 'a', 'new', 'world']print(functools.reduce(lambda x, y: x+y, words))
결과)thisisanewworld
# 시퀀스 타입이 정수일 때 처리import functools
nums = range(1, 10)print(functools.reduce(lambda x, y: x+y, nums))
결과)55
# reduce() 함수에서 다음의 동작은 허용되지 않는다.import functools
words = ['this', 'is', 'a', 'new', 'world']print(functools.reduce(lambda x, y: len(x) + len(y), words))
결과)TypeError: object of type 'int' has no len()
# 직접 인자로 주면 동작한다.import functools
print(functools.reduce(lambda x, y: len(x) + len(y), ['hello', 'apple']))
결과)10
# 인자로 주어진 스트링 길이의 합을 구하고 싶을때print(sum(map(len, words)))
결과)15# 시퀀스 형 데이터의 참, 거짓에 따라 참만 골라내고 싶을때는 filter() 함수를 사용한다.n = range(1, 11)print(list(filter(lambda x: x % 2 == 0, n)))
결과)[2, 4, 6, 8, 10]
# yield 키워드
def inclusiveRange(start, stop, step = 1): i = start while i <= stop: yield i i += step
for i in inclusiveRange(0, 10, 1): print(i, end = ' ')
결과)0 1 2 3 4 5 6 7 8 9 10
# default argument 에러
def inclusiveRange(start = 0, stop, step = 1): i = start while i <= stop: yield i i += step
# for i in inclusiveRange(0, 10, 1):for i in inclusiveRange(25): print(i, end = ' ')
결과)SyntaxError: non-default argument follows default argument
# 함수 인자에 대한 직접 처리def inclusiveRange(*args): lenArgs = len(args) if lenArgs < 1: raise TypeError('more argument is needed.') elif lenArgs == 1: start = 0 stop = args[0] step = 1 elif lenArgs == 2: (start, stop) = args step = 1 elif lenArgs == 3: (start, stop, step) = args else: raise TypeError('not admitted more than 3 arguments: '.format(lenArgs))
i = start while i <= stop: yield i i += step
for i in inclusiveRange(1, 25): print(i, end = ' ')
결과)1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
# 함수 인자에 대한 자동 처리
def show(a, b, c):
print(a, b ,c)
ls = list(range(1, 4))
show(*(ls))
# 결과
1 2 3
댓글 영역