경기도 인공지능 개발 과정/Python

Python 함수, lambda 함수

agingcurve 2022. 5. 28. 14:50
반응형

Python 함수

학습목표

  1. 함수를 이해하고 활용 할 수 있다.

 

함수란?

  • 지금까지 무심코 코드에서 사용된 많은 함수들이 존재 한다.
  • 예를들면, sum, len, range 같은 함수 등이 있다.
  • 함수란 우리가 알고있는 개념처럼 주어진 입력(input)에 대해서 의도된 출력(output)를 전달하는 역할을 한다.
  • python 내부에 이미 정의(구현)된 함수를 내장함수(built-in function)이라고 한다.
In [3]:
a = [1,2,3,4,44,7854,4,88]
print(a.sort())
a
None
Out[3]:
[1, 2, 3, 4, 4, 44, 88, 7854]
In [4]:
a = [5,5,4,74,98,4,3]
print(sorted(a))
[3, 4, 4, 5, 5, 74, 98]
In [6]:
print(sorted(a))
[3, 4, 4, 5, 5, 74, 98]

함수의 정의

def 함수명(매개변수):
    수행할문장들..
  • def 키워드 사용한다.
  • 매개변수란 함수에 입력으로 전달하는 값을 의미한다.parameter라고 한다.
  • : (콜론)
  • body (함수의 구현 부분, 함수 역시 코드 블록이기 때문에 들여쓰기 된 부분까지 함수의 코드블록으로 인지 함)
    • 함수를 호출한 코드 (caller)로 함수가 해당 기능을 수행하고 완료된 값(output)을 전달하기 위해 return 키워드 사용한다.
    • 즉, return 이후에 오는 값을 caller로 전달한다.
  • 함수의 네이밍 무척 중요하다.
    • 즉, 어떤 기능을 하는 함수인지 이름으로 최대한 나타날 수 있게 해야한다.
In [8]:
def my_add(value1, value2):
    result = value1+value2
    return result


result_value = my_add(2,4)

print(result_value)
6

함수의 사용(호출)

  • 함수명(argument1, argument2, ... argumentn)
  • 위와 같이 정의 된 함수의 이름과 전달되는 argument(인수)를 괄호안에 전달하여 함수를 호출
  • 함수가 호출되면 실행의 흐름이 호출자(caller)에서 함수(callee)로 변경 된다.
In [9]:
print(my_add(6,8))
14
In [10]:
print(my_add(1,3,4))
--------------------------------------------
TypeError  Traceback (most recent call last)
Input In [10], in <cell line: 1>()
----> 1 print(my_add(1,3,4))

TypeError: my_add() takes 2 positional arguments but 3 were given

parameter

  • 함수에 전달되는 입력(input)
  • 입력이 필요하지 않을 수도, 1개의 입력만 있을 수도, 여러개의 입력이 존재할 수 도 있다.
  • 파라미터로 int, string, float, boolean, list, dict 등등 어떤 파이썬 객체도 전달 가능하다.
  • 심지어, 함수도 함수의 파라미터로 전달 가능하다.
  • python의 경우, 타입 명시가 없기 때문에, 함수 생성 시, 의도된 파라미터의 타입에 맞게 입력을 전달하는 것이 중요하다.
  • 또한 파라미터를 전달 할 때, 정의된 순서에 따라 값을 전달하는 것이 중요하다.
In [16]:
def print_num(a,b,c):
    print(a)
    print(b)
    print(c)
    
print_num(23,54,6)

list_a = [66,33,22]


print_num(list_a)  #오류발생..  왜?? 

print_num(*list_a)
23
54
6
66
33
22
In [13]:
def gugu_print(dan):
    #구현해보아요... 
    print(dan,"단")
    for i in range(1,10):
        print(f'{dan}*{i}={dan*i}')
    print("==========================")
    
gugu_print(3)
gugu_print(8)

gugu_print('a')
3 단
3*1=3
3*2=6
3*3=9
3*4=12
3*5=15
3*6=18
3*7=21
3*8=24
3*9=27
==========================
8 단
8*1=8
8*2=16
8*3=24
8*4=32
8*5=40
8*6=48
8*7=56
8*8=64
8*9=72
==========================
a 단
a*1=a
a*2=aa
a*3=aaa
a*4=aaaa
a*5=aaaaa
a*6=aaaaaa
a*7=aaaaaaa
a*8=aaaaaaaa
a*9=aaaaaaaaa
==========================

Default parameter (기본 인자)

  • 함수의 파라미터에 기본값 지정 가능하다.
  • 파라미터를 명시하지 않을 경우, 지정된 기본값으로 대체한다.
  • 디폴트 파라미터 뒤에 일반 파라미터가 위치할 수 없다.
In [17]:
print('abc')
abc
In [23]:
print('abc',end='bye~~')
print('test')
print('tttt')
abcbye~~test
tttt
In [21]:
def test_add(x, y=10, z = 5):
    return x+y+z

test_add(10)
test_add(10,23)
test_add(1,32,5)
Out[21]:
38
  • 기본 파라미터의 다른 예
    • print 함수
      • sep, end, file등 여러 기본 파라미터를 가짐
In [24]:
def test2(x,y,z):
    print('x : ',x)
    print('y : ',y)
    print('z : ', z)
    
test2(3,4,5)
x :  3
y :  4
z :  5
In [25]:
 
x :  10
y :  20
z :  8

keyword parameter (키워드 파라미터)

  • 파이썬의 경우, 파라미터에 값을 전달 할 때, 파라미터의 이름을 명시하여 전달 가능하다.
  • 파라미터 이름을 사용하지 않을 경우, 기본적으로 순서에 맞게 전달한다.
In [26]:
test2(y=20,x=10,z=8)
x :  10
y :  20
z :  8
In [30]:
def person_info(name,phone,address):
    print('이름:',name)
    print('전화번호:',phone)
    print('주소:',address)
    
person_info('kang','010-111-1111','경기도 고양시')

person = {'name':'kang','address':'경기도 고양시','phone':'010-111-1111'}

person_info(**person)
이름: kang
전화번호: 010-111-1111
주소: 경기도 고양시
이름: kang
전화번호: 010-111-1111
주소: 경기도 고양시

return (리턴)

  • 함수의 종료를 명시한다.
    • return 옆에 값이나 수식이 있다면 해당 값을 호출자(caller)에게 반환(전달)한다.
    • return 만 존재하면 None을 반환
    • return이 없는 경우, 함수 코드 블록이 종료되면 종료된다. 이때도 None을 반환한다.
In [1]:
print('1번문장')
print('2번문장')
print('3번문장')
print('4번문장')

def test():
    print('5번문장')
    
print('6')
print('7')

test()

print('8')
print('9')
1번문장
2번문장
3번문장
4번문장
6
7
5번문장
8
9
In [ ]:
 
In [ ]:
 

multiple return (복수 값 반환)

  • tuple반환을 하여 복수개의 값 리턴 가능하다.
In [3]:
def mult_return(x,y):
    s = x+100
    m = y + 200
    return s,m

a,b = mult_return(2,3)
print(a,b)

print(type(mult_return(2,3)))
102 203
<class 'tuple'>
In [6]:
def hello():
    pass

hello()
  Input In [6]
    hello()
    ^
IndentationError: expected an indented block
In [7]:
def my_func(a):
    '''
    이 함수는 매개변수로 입력 받은 문자를 출력하는 함수입니다.
    '''
    print(a)
    
my_func('hello')
hello
In [8]:
my_func.__doc__
Out[8]:
'\n    이 함수는 매개변수로 입력 받은 문자를 출력하는 함수입니다.\n    '
In [9]:
str.__doc__
Out[9]:
"str(object='') -> str\nstr(bytes_or_buffer[, encoding[, errors]]) -> str\n\nCreate a new string object from the given object. If encoding or\nerrors is specified, then the object must expose a data buffer\nthat will be decoded using the given encoding and error handler.\nOtherwise, returns the result of object.__str__() (if defined)\nor repr(object).\nencoding defaults to sys.getdefaultencoding().\nerrors defaults to 'strict'."
In [10]:
sorted.__doc__
Out[10]:
'Return a new list containing all items from the iterable in ascending order.\n\nA custom key function can be supplied to customize the sort order, and the\nreverse flag can be set to request the result in descending order.'

variable scope (변수의 범위)

  • 변수가 참조 가능한 코드상의 범위를 명시한다.
  • 함수내의 변수는 자신이 속한 코드 블록이 종료되면 소멸된다.
  • 이렇게 특정 코드 블록에서 선언된 변수를 지역변수(local variable) 라고한다.
  • 반대로 가장 상단에서 정의되어 프로그램 종료 전까지 유지되는 변수를 전역변수(global variable)라고한다.
  • 같은 이름의 지역변수와 전역변수가 존재할 경우, 지역변수의 우선순위가 더 높다.
In [ ]:
a = 1 
def var_test(a):
    a = a +1 
    
var_test(a)
print(a)
In [12]:
a = 1 
def var_test(bbbb):
    bbbb = bbbb +1 
    
var_test(a)
print(bbbb)
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Input In [12], in <cell line: 6>()
      3     bbbb = bbbb +1 
      5 var_test(a)
----> 6 print(bbbb)

NameError: name 'bbbb' is not defined
In [20]:
g_val = 10 
def add_10():
    global g_val
    g_val = g_val+ 10
    print(g_val)

add_10()
print(g_val)
20
20
In [19]:
g_val = 10

def test2(g):
    g += 20
    return g
g_val = test2(g_val)

print(g_val)
30
In [ ]:
# global 
In [27]:
globals()
Out[27]:
{'__name__': '__main__',
 '__doc__': 'Automatically created module for IPython interactive environment',
 '__package__': None,
 '__loader__': None,
 '__spec__': None,
 '__builtin__': <module 'builtins' (built-in)>,
 '__builtins__': <module 'builtins' (built-in)>,
 '_ih': ['',
  "print('1번문장')\nprint('2번문장')\nprint('3번문장')\nprint('4번문장')\n\ndef test():\n    print('5번문장')\n    \nprint('6')\nprint('7')\n\ntest()\n\nprint('8')\nprint('9')",
  'def mult_return(x,y):\n    s = x+100\n    m = y + 200\n    return s,m\n\na,b = mult_return(2,3)\nprint(a,b)',
  'def mult_return(x,y):\n    s = x+100\n    m = y + 200\n    return s,m\n\na,b = mult_return(2,3)\nprint(a,b)\n\nprint(type(mult_return(2,3)))',
  'def hello:\n    pass\n\nhello()',
  'def hello():\n    pass\n\nhello()',
  'def hello():\n    \n\nhello()',
  "def my_func(a):\n    '''\n    이 함수는 매개변수로 입력 받은 문자를 출력하는 함수입니다.\n    '''\n    print(a)\n    \nmy_func('hello')",
  'my_func.__doc__',
  'str.__doc__',
  'sorted.__doc__',
  'a = 1 \ndef var_test(b):\n    b = b +1 \n    \nvar_test(a)\nprint(b)',
  'a = 1 \ndef var_test(bbbb):\n    bbbb = bbbb +1 \n    \nvar_test(a)\nprint(bbbb)',
  'g_val = 10 \ndef test():\n    print(g_val)\n    ',
  'g_val = 10 \ndef test():\n    print(g_val)\n\ntest()',
  'g_val = 10 \ndef test():\n    g_val += 10\n    print(g_val)\n\ntest()',
  'g_val = 10 \ndef test():\n    g_val = g_val+ 10\n    print(g_val)\n\ntest()',
  'g_val = 10 \ndef test():\n    global g_val\n    g_val = g_val+ 10\n    print(g_val)\n\ntest()',
  'g_val = 10 \ndef test():\n    global g_val\n    g_val = g_val+ 10\n    print(g_val)\n\ntest()\nprint(g_val)',
  'g_val = 10\n\ndef test2(g):\n    g += 20\n    return g\ng_val = test2(g_val)\n\nprint(g_val)',
  'g_val = 10 \ndef add_10():\n    global g_val\n    g_val = g_val+ 10\n    print(g_val)\n\nadd_10()\nprint(g_val)',
  'locals()',
  'globals()',
  'def test():\n    a = 10\n    locals()\n    \nprint()',
  'def test():\n    a = 10\n    print(locals())\n    \ntest()',
  'aa =10\nbb = 20\n\ndef test():\n    a = 10\n    print(locals())\n    \ntest()',
  'aa =10\nbb = 20\n\ndef test():\n    a = 10\n    print(locals())\n    \ntest()\n\nglobals()',
  'globals()'],
 '_oh': {8: '\n    이 함수는 매개변수로 입력 받은 문자를 출력하는 함수입니다.\n    ',
  9: "str(object='') -> str\nstr(bytes_or_buffer[, encoding[, errors]]) -> str\n\nCreate a new string object from the given object. If encoding or\nerrors is specified, then the object must expose a data buffer\nthat will be decoded using the given encoding and error handler.\nOtherwise, returns the result of object.__str__() (if defined)\nor repr(object).\nencoding defaults to sys.getdefaultencoding().\nerrors defaults to 'strict'.",
  10: 'Return a new list containing all items from the iterable in ascending order.\n\nA custom key function can be supplied to customize the sort order, and the\nreverse flag can be set to request the result in descending order.',
  21: {...},
  22: {...},
  26: {...}},
 '_dh': [WindowsPath('c:/ai/ai_2205/python')],
 'In': ['',
  "print('1번문장')\nprint('2번문장')\nprint('3번문장')\nprint('4번문장')\n\ndef test():\n    print('5번문장')\n    \nprint('6')\nprint('7')\n\ntest()\n\nprint('8')\nprint('9')",
  'def mult_return(x,y):\n    s = x+100\n    m = y + 200\n    return s,m\n\na,b = mult_return(2,3)\nprint(a,b)',
  'def mult_return(x,y):\n    s = x+100\n    m = y + 200\n    return s,m\n\na,b = mult_return(2,3)\nprint(a,b)\n\nprint(type(mult_return(2,3)))',
  'def hello:\n    pass\n\nhello()',
  'def hello():\n    pass\n\nhello()',
  'def hello():\n    \n\nhello()',
  "def my_func(a):\n    '''\n    이 함수는 매개변수로 입력 받은 문자를 출력하는 함수입니다.\n    '''\n    print(a)\n    \nmy_func('hello')",
  'my_func.__doc__',
  'str.__doc__',
  'sorted.__doc__',
  'a = 1 \ndef var_test(b):\n    b = b +1 \n    \nvar_test(a)\nprint(b)',
  'a = 1 \ndef var_test(bbbb):\n    bbbb = bbbb +1 \n    \nvar_test(a)\nprint(bbbb)',
  'g_val = 10 \ndef test():\n    print(g_val)\n    ',
  'g_val = 10 \ndef test():\n    print(g_val)\n\ntest()',
  'g_val = 10 \ndef test():\n    g_val += 10\n    print(g_val)\n\ntest()',
  'g_val = 10 \ndef test():\n    g_val = g_val+ 10\n    print(g_val)\n\ntest()',
  'g_val = 10 \ndef test():\n    global g_val\n    g_val = g_val+ 10\n    print(g_val)\n\ntest()',
  'g_val = 10 \ndef test():\n    global g_val\n    g_val = g_val+ 10\n    print(g_val)\n\ntest()\nprint(g_val)',
  'g_val = 10\n\ndef test2(g):\n    g += 20\n    return g\ng_val = test2(g_val)\n\nprint(g_val)',
  'g_val = 10 \ndef add_10():\n    global g_val\n    g_val = g_val+ 10\n    print(g_val)\n\nadd_10()\nprint(g_val)',
  'locals()',
  'globals()',
  'def test():\n    a = 10\n    locals()\n    \nprint()',
  'def test():\n    a = 10\n    print(locals())\n    \ntest()',
  'aa =10\nbb = 20\n\ndef test():\n    a = 10\n    print(locals())\n    \ntest()',
  'aa =10\nbb = 20\n\ndef test():\n    a = 10\n    print(locals())\n    \ntest()\n\nglobals()',
  'globals()'],
 'Out': {8: '\n    이 함수는 매개변수로 입력 받은 문자를 출력하는 함수입니다.\n    ',
  9: "str(object='') -> str\nstr(bytes_or_buffer[, encoding[, errors]]) -> str\n\nCreate a new string object from the given object. If encoding or\nerrors is specified, then the object must expose a data buffer\nthat will be decoded using the given encoding and error handler.\nOtherwise, returns the result of object.__str__() (if defined)\nor repr(object).\nencoding defaults to sys.getdefaultencoding().\nerrors defaults to 'strict'.",
  10: 'Return a new list containing all items from the iterable in ascending order.\n\nA custom key function can be supplied to customize the sort order, and the\nreverse flag can be set to request the result in descending order.',
  21: {...},
  22: {...},
  26: {...}},
 'get_ipython': <bound method InteractiveShell.get_ipython of <ipykernel.zmqshell.ZMQInteractiveShell object at 0x000002F056042EE0>>,
 'exit': <IPython.core.autocall.ZMQExitAutocall at 0x2f0560745b0>,
 'quit': <IPython.core.autocall.ZMQExitAutocall at 0x2f0560745b0>,
 '_': {...},
 '__': {...},
 '___': {...},
 '_i': 'aa =10\nbb = 20\n\ndef test():\n    a = 10\n    print(locals())\n    \ntest()\n\nglobals()',
 '_ii': 'aa =10\nbb = 20\n\ndef test():\n    a = 10\n    print(locals())\n    \ntest()',
 '_iii': 'def test():\n    a = 10\n    print(locals())\n    \ntest()',
 '_i1': "print('1번문장')\nprint('2번문장')\nprint('3번문장')\nprint('4번문장')\n\ndef test():\n    print('5번문장')\n    \nprint('6')\nprint('7')\n\ntest()\n\nprint('8')\nprint('9')",
 'test': <function __main__.test()>,
 '_i2': 'def mult_return(x,y):\n    s = x+100\n    m = y + 200\n    return s,m\n\na,b = mult_return(2,3)\nprint(a,b)',
 'mult_return': <function __main__.mult_return(x, y)>,
 'a': 1,
 'b': 203,
 '_i3': 'def mult_return(x,y):\n    s = x+100\n    m = y + 200\n    return s,m\n\na,b = mult_return(2,3)\nprint(a,b)\n\nprint(type(mult_return(2,3)))',
 '_i4': 'def hello:\n    pass\n\nhello()',
 '_i5': 'def hello():\n    pass\n\nhello()',
 'hello': <function __main__.hello()>,
 '_i6': 'def hello():\n    \n\nhello()',
 '_i7': "def my_func(a):\n    '''\n    이 함수는 매개변수로 입력 받은 문자를 출력하는 함수입니다.\n    '''\n    print(a)\n    \nmy_func('hello')",
 'my_func': <function __main__.my_func(a)>,
 '_i8': 'my_func.__doc__',
 '_8': '\n    이 함수는 매개변수로 입력 받은 문자를 출력하는 함수입니다.\n    ',
 '_i9': 'str.__doc__',
 '_9': "str(object='') -> str\nstr(bytes_or_buffer[, encoding[, errors]]) -> str\n\nCreate a new string object from the given object. If encoding or\nerrors is specified, then the object must expose a data buffer\nthat will be decoded using the given encoding and error handler.\nOtherwise, returns the result of object.__str__() (if defined)\nor repr(object).\nencoding defaults to sys.getdefaultencoding().\nerrors defaults to 'strict'.",
 '_i10': 'sorted.__doc__',
 '_10': 'Return a new list containing all items from the iterable in ascending order.\n\nA custom key function can be supplied to customize the sort order, and the\nreverse flag can be set to request the result in descending order.',
 '_i11': 'a = 1 \ndef var_test(b):\n    b = b +1 \n    \nvar_test(a)\nprint(b)',
 'var_test': <function __main__.var_test(bbbb)>,
 '_i12': 'a = 1 \ndef var_test(bbbb):\n    bbbb = bbbb +1 \n    \nvar_test(a)\nprint(bbbb)',
 '_i13': 'g_val = 10 \ndef test():\n    print(g_val)\n    ',
 'g_val': 20,
 '_i14': 'g_val = 10 \ndef test():\n    print(g_val)\n\ntest()',
 '_i15': 'g_val = 10 \ndef test():\n    g_val += 10\n    print(g_val)\n\ntest()',
 '_i16': 'g_val = 10 \ndef test():\n    g_val = g_val+ 10\n    print(g_val)\n\ntest()',
 '_i17': 'g_val = 10 \ndef test():\n    global g_val\n    g_val = g_val+ 10\n    print(g_val)\n\ntest()',
 '_i18': 'g_val = 10 \ndef test():\n    global g_val\n    g_val = g_val+ 10\n    print(g_val)\n\ntest()\nprint(g_val)',
 '_i19': 'g_val = 10\n\ndef test2(g):\n    g += 20\n    return g\ng_val = test2(g_val)\n\nprint(g_val)',
 'test2': <function __main__.test2(g)>,
 '_i20': 'g_val = 10 \ndef add_10():\n    global g_val\n    g_val = g_val+ 10\n    print(g_val)\n\nadd_10()\nprint(g_val)',
 'add_10': <function __main__.add_10()>,
 '_i21': '\nlocals()',
 '_21': {...},
 '_i22': 'globals()',
 '_22': {...},
 '_i23': 'def test():\n    a = 10\n    locals()\n    \nprint()',
 '_i24': 'def test():\n    a = 10\n    print(locals())\n    \ntest()',
 '_i25': 'aa =10\nbb = 20\n\ndef test():\n    a = 10\n    print(locals())\n    \ntest()',
 'aa': 10,
 'bb': 20,
 '_i26': 'aa =10\nbb = 20\n\ndef test():\n    a = 10\n    print(locals())\n    \ntest()\n\nglobals()',
 '_26': {...},
 '_i27': 'globals()'}
In [29]:
def test():
    a = 10
    b = 20
    print(locals())

test()
{'a': 10, 'b': 20}

variable length argument (가변길이 인자)

  • 전달되는 파라미터의 개수가 가변적일때 사용한다.
  • 예를들면 print 함수나 format 함수를 생각해 볼 수 있다.
    • args : 파라미터를 튜플의 형태로 전달
    • kwargs : 파리미터를 딕셔너리 형태로 전달(네임드 파라미터)
    def 함수이름(*매개변수): 
        수행할 문장
    ...
    def 함수이름(**kwargs): 
        수행할 문장
In [30]:
print(1)
1
In [31]:
print(1,2,34,45,)
1 2 34 45
In [34]:
def func(*a):
  #  print(type(a))
    for i in a :
        print(i)
    
func(1,2,3)
1
2
3
In [35]:
func(1)
1
In [36]:
func(1,2,3,4,5,67,)
1
2
3
4
5
67
In [39]:
#입력값을 모두 더하는 함수를 구현해 보세요.  

def add_all(*args):
#     return sum(args)
    total = 0
    for value in args:
        total += value
    return total

print(add_all(1))
print(add_all(1,2,3))
print(add_all(1,4,5,))
print(add_all(1,55,2,5,4,6,5,4))
1
6
10
82

keyword parameter (키워드 파라미터)

  • **가 붙은 경우에는 키워드 파라미터로 인식
  • 즉 함수 호출 시, 파리미터의 이름과 값을 함께 전달 가능
In [42]:
def func2(**kwargs):
    for key, value in kwargs.items():
        print(key,value)
        
func2(a=1)
func2(test=1, test2=32)
func2(name='kang',age=20,phone='010-111-1111')
a 1
test 1
test2 32
name kang
age 20
phone 010-111-1111

위치 인수와 키워드 인수를 함께 사용하기

In [46]:
def my_func(*args,**kwargs):
    print(*args,**kwargs)
    
my_func(1,2,3,sep='\t',end='\tend')
1	2	3	end
In [47]:
my_func(1,2,3,3,4,6,7,8, sep='\t',end='\tend')
1	2	3	3	4	6	7	8	end
In [48]:
my_func(1,2,3,3,4,6,7,8, sep='\t',end='\tend',3,3,54) #에러~~  
  Input In [48]
    my_func(1,2,3,3,4,6,7,8, sep='\t',end='\tend',3,3,54)
                                                        ^
SyntaxError: positional argument follows keyword argument

연습문제

  1. 리스트를 입력받아서 리스트의 요소중 중복된 값은 삭제하고, 유일한 값만 유지하는 리스트를 반환하는 함수를 정의 하세요.

입력 예 [1,2,2,3,4,5,4]

출력 예 [1,2,3,4,5]


  1. 문자열 두개를 인자로 전달받아 길이가 더 긴 문자열을 반환하는 함수를 정의하세요. 단, 두개의 길이가 같다면 첫번째 인자를 반환하세요.

입력 예 'test' 'python' 출력 예 'python'

입력 예 'java' 'test' 출력 예 'java'


  1. 입력받은 인자중에 가장 큰 값을 구하는 함수를 작성하세요. 단, 입력받는 인자의 개수는 정해져 있지 않습니다.

입력 예 : 100, 22,44,65,33,55,22 출력 예 : 100

입력 예 : 44,22 출력 예 : 44

입력 예 : 55,33,665,22,223 출력 예 : 665


In [49]:
x = [1,2,2,3,4,5,4]

def set_list(x):
    return list(set(x))

set_list(x)
Out[49]:
[1, 2, 3, 4, 5]
In [50]:
def max_len(x, y):
    if len(x)<len(y): 
        print(y)
    else:
        print(x)
        
x = 'test' 
y = 'python'
max_len(x, y)
python
In [51]:
def max_find(*nums):
    return max(nums)

max_find(1,2,3,4,100,20)
Out[51]:
100
In [56]:
value_list = input().split()
int_list=[]
for value in value_list:
    int_list.append(int(value))

print(int_list)

max_find(*int_list)
333 32 54
[333, 32, 54]
Out[56]:
333
In [58]:
m_list = list(map(int,value_list))
print(m_list)
#map(함수, 반복가능한자료형)

max_find(*list(map(int,input().split())))
[333, 32, 54]
33 32 5
Out[58]:
33

---------------------------------------------------- 

Lamda 함수

학습목표

  1. Lambda 함수를 이해하고, 사용할 수 있다.
  • Lambda 함수
    • 단일문으로 표현되는 익명함수이다.
    • 익명함수란 이름이 없는 구현체만 존재하는 간단한 함수를 의미한다.
    • 코드 상에서 한번만 사용되는 기능이 있을 때, 굳이 함수로 만들지 않고 1회성으로 만들어서 쓸 때 사용한다.
    • lambda 예약어로 만든 함수는 return 명령어가 없어도 결괏값을 돌려준다.
In [3]:
def add(a,b):
    return a+b

print(add(2,3))

a = lambda a, b : a+b
a(2,4)
5
Out[3]:
6
In [4]:
(lambda a, b : a+b)(3,4)
Out[4]:
7
In [7]:
def tt(s):
    return len(s)
print(tt('dkfjdkjfd'))

(lambda s : len(s) )('dkfjdkf')
9
Out[7]:
7
In [8]:
def add(a,b):
    return a+b

obj = [1,2,3]

(lambda add, obj : [add(x,x+1) for x in obj])(add,obj)
Out[8]:
[3, 5, 7]
In [9]:
def ttt(add,obj):
    result_list = []
    for x in obj:
        result_list.append(add(x,x+1))
    return result_list

ttt(add,obj)
Out[9]:
[3, 5, 7]

filter, map, reduce

  • lambda가 유용하게 사용되는 3가지 대표적 함수이다.
  • 함수형 프로그래밍의 기본 요소이기도 하다.
  • filter : 특정 조건을 만족하는 요소만 남기고 필터링한다.
  • map : 각 원소를 주어진 수식에 따라 변형하여 새로운 리스트를 반환한다.
  • reduce : 차례대로 앞 2개의 원소를 가지고 연산. 연산의 결과가 또 다음 연산의 입력으로 진행된다. 따라서 마지막까지 진행되면 최종 출력은 한개의 값만 남게 된다.
In [10]:
list_a = [23,245,55,77,44,94]

#리스트에서 짝수인 값들만 새로운 리스트에 담아서 리턴하세요.
result_list = []
for value in list_a:    
    if value % 2 == 0:
        result_list.append(value)

print(result_list)
[44, 94]
In [13]:
def even(n):
    return n % 2 == 0

even(2)

result_list = []
for value in list_a:    
    if even(value):
        result_list.append(value)

print(result_list)
[44, 94]
In [15]:
list(filter(even,list_a))
Out[15]:
[44, 94]
In [16]:
list(filter(lambda n:n%2==0 ,list_a))
Out[16]:
[44, 94]
In [17]:
list(filter(lambda n:n%2!=0 ,list_a))
Out[17]:
[23, 245, 55, 77]
In [18]:
list(filter(lambda n:n%3==0 ,list_a))
Out[18]:
[]
In [20]:
def f(x):
    return x > 5 and x < 10
a = [8, 3, 2, 10, 15, 7, 1, 9, 0, 11]
print(list(filter(f, a)))


#함수 f를 람다표현식으로 바꾸기
print(list(filter(lambda x : x > 5 and x < 10 , a)))
[8, 7, 9]
[8, 7, 9]
In [22]:
# map
# 주어진 리스트, 리스트의 제곱을한 숫자로 새로운 리스트
nums = [1, 2, 3, 6, 8, 9, 10, 11, 13, 15]
 
def f(n):
    return n**2

list(map(lambda n : n**2 , nums))
Out[22]:
[1, 4, 9, 36, 64, 81, 100, 121, 169, 225]
In [23]:
list(map(lambda n : n %2== 0 , nums))
Out[23]:
[False, True, False, True, True, False, True, False, False, False]
In [5]:
#람다 표현식을 인수로 사용하기  ex) map 
In [28]:
#람다 표현식에 조건부 표현식 사용하기
#lambda 매개변수들: 식1 if 조건식 else 식2

a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
result_list = list(map(lambda x : str(x) if x % 3 == 0 else x , a))
print(result_list)

def test(x):
    if x % 3 == 0:
        return str(x)
    else:
        return x
test(3)
    
[1, 2, '3', 4, 5, '6', 7, 8, '9', 10]
Out[28]:
'3'
In [29]:
#lambda 매개변수들: 식1 if 조건식1 else 식2 if 조건식2 else 식3
# 이렇게 가독성이 떨어질 때에는 그냥 def 함수로 만들고 if elif else 사용권장
a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

list(map(lambda x : str(x) if x == 1 else float(x) if x == 2 else x+10, a))
Out[29]:
['1', 2.0, 13, 14, 15, 16, 17, 18, 19, 20]
In [8]:
#map에 객체를 여러 개 넣기
#map은 리스트 등의 반복 가능한 객체를 여러 개 넣을 수도 있습니다. 
#다음은 두 리스트의 요소를 곱해서 새 리스트를 만듭니다.

a = [1, 2, 3, 4, 5]
b = [2, 4, 6, 8, 10]
list(map(lambda x, y: x * y, a, b))
Out[8]:
[2, 8, 18, 32, 50]

reduce 사용하기

  • from functools import reduce
  • reduce(함수, 반복가능한객체)

반복되는 객체에서 인자를 두개씩 사용해서 결과값을 만들고 결과값과 다음 인자로 또 함수를 실행하는 것을 반복 한다.

In [31]:
# reduce 사용하기
#  from functools import reduce
#  reduce(함수, 반복가능한객체)
from functools import reduce

a = [1,2,3,4,5]

# 1.  x = 1, y = 2  결과 3 
# 2. 1번에서 수행한 결과값 x = 3, y = 3   결과 6
# 3. 2의결과값 6 + 4 
# 4. 3의 결과값 10 + 5 
# 최종 결과값이 15 


reduce(lambda x,y : x+y , a)
Out[31]:
15
In [9]:
from functools import reduce


a = [1, 3, 5, 8]
# 리스트 내의 모든 숫자의 합
In [40]:
def factorial(n):
    if n == 0:
        return 1
    else:
        return n * factorial(n-1)
print(factorial(5))
120
In [36]:
n = [5,4,3,2,1]
f = reduce(lambda x,y : x*y , n)

print(f)
120
In [38]:
# List Comprehesions 

a = [3,33,22,44,25,66,4,3,6]

[i for i in a if i>20 and i < 40]
Out[38]:
[33, 22, 25]

함수 연습문제

  1. 주어진 숫자 리스트의 평균을 구하는 함수를 출력하시오
  2. 해당 숫자가 소수인지 아닌지 판별하시오.
  3. 2부터 해당 숫자사이에 소수가 몇개인지 출력하는 함수를 구하시오
In [49]:
nums = [3,33,22,44,25,66,4,3,6]
print(sum(nums)/len(nums))
def getAvg(nums):
    return sum(nums)/len(nums)

getAvg(nums)
22.88888888888889
Out[49]:
22.88888888888889
In [47]:
def isPrime(n):
    for i in range(2, n):
        if n%i == 0:
            return False
    return True

isPrime(9)
Out[47]:
False
In [45]:
def getPrimeNum(n):
    cnt = 0
    for i in range(2, n):
        if isPrime(i):
            cnt += 1
    return cnt

getPrimeNum(100)
Out[45]:
25

클로저

  • 변수의 사용범위 지역변수, 전역변수, global 확인
  • https://dojang.io/mod/page/view.php?id=2364 참고
  • 클로저(closure)란, 외부 함수에 접근할 수 있는 내부 함수
  • 혹은 이러한 원리를 일컫는 용어인데 스코프에 따라서 내부함수의 범위에서는 외부 함수 범위에 있는 변수에 접근이 가능하지만 그 반대는 실현이 불가능하다는 개념이다.
  • 특징으로는 외부함수는 외부함수의 지역변수를 사용하는 내부함수가 소멸될 때까지 소멸되지 않는다.예를 들어 한 함수안에 다른 함수가 있다면 그 안의 함수는 바깥에 정의해놓은 변수를 사용할 수 있지만 그 반대는 가능하지 않다.
In [12]:
#전역변수, 지역변수 이해. 
# name = 'kim'
def foo():
#     global name 
    name = 'kang'
    print(locals())
    
#     name = 'kang'
#     return name
# print(globals())    
foo()
print(name)
{'name': 'kang'}
kang
In [ ]:
# 함수의 중첩

def hello():
    message = 'hello python'
    def say_hello():
        print(message)
    say_hello()

hello()
In [16]:
def a():
    x = 10
    def b():
        x = 20
    b()
    print(x)
    
a()
10
In [17]:
# nonlocal 
def a():
    x = 10
    def b():
        nonlocal x
        x = 20
    b()
    print(x)
    
a()
20
In [21]:
def A():
    x = 10
    y = 100
    def B():
        x = 20
        def C():
            nonlocal x
            nonlocal y
            x = x + 30
            y = y + 300
            print(x)
            print(y)
        C()
    B()
 
A()
50
400
In [22]:
x = 1
def A():
    x = 10
    def B():
        x = 20
        def C():
            global x
            x = x + 30
            print(x)
        C()
    B()
 
A()
31
In [25]:
x = 1
y = 10
def A():
    x = 10
    y = 100
    def B():
        x = 20
#         y = 200 
        def C():
            global x
            nonlocal y
            y = y+100
            x = x + 30
            print(x,y)
        C()
    B()
 
A()
31 200
In [28]:
#일급객체 
def my_func():
    name = 'kang'
    def hello():
        print('hi!!!!', name)
    return hello

my_func()()

return_value = my_func()
return_value()
hi!!!! kang
hi!!!! kang
In [31]:
def cal():
    a = 10
    b = 20
    def add_mul(x):
        return a+b+x
    return add_mul

cc = cal()

print(cc(23))
print(cc(2))
53
32
In [34]:
def times_multiply(n):
    def multiply(x):
        return n * x 
    return multiply

times_3 = times_multiply(3)
times_4 = times_multiply(4)

del times_multiply

print(times_3(5))
print(times_4(5))

times_20 = times_multiply(20)
15
20
---------------------------------------------------------------------
NameError                           Traceback (most recent call last)
Input In [34], in <cell line: 14>()
     11 print(times_3(5))
     12 print(times_4(5))
---> 14 times_20 = times_multiply(20)

NameError: name 'times_multiply' is not defined

연습문제

호출횟수를 세는 함수 만들기. c를 호출 할 때마다 호출 횟수가 출력되도록 작성

def counter():
    i = 0
    def count():

        ...


c = counter()
for i in range(10):
    print(c(), end=' ')
In [35]:
def counter():
    i = 0
    def count():       
        nonlocal i
        i += 1
        return i
    return count

c = counter()
for i in range(10):
    print(c(), end=' ')
1 2 3 4 5 6 7 8 9 10