Walrus 연산자


이 글은 파이썬 코딩의 기술(브렛 슬라킨 지음)을 읽고 정리하는 글입니다.

Walurs 연산자란?

대입식 이라고 하며 파이썬의 고질적인 코드중복 문제를 해결하기 위해 3.8에 새로 도입된 구문이다. 아래와 같이 사용한다.

1
a := b

바다코끼리를 연상시켜서 walrus라고 한다. :=

기능

일반 대입문이 사용되지 못하는 위치에서 변수에 값을 대입할 수 있다.

  • while, if문의 조건식
    이를 통하여 코드의 길이를 줄이고 가독성을 높여 두마리 토끼를 잡을 수 있다

예시

일반적인 while break 문

1
2
3
4
5
6
while True:
flag = get_flag()
if flag:
break
else:
# Task 코드

walrus를 사용한 while문

1
2
while flag := get_flag():
# Task 코드

reference

cudatoolkit 버전별로 관리하기


Anaconda를 이용한 환경별 Cuda Version 관리

  1. conda-forge 채널을 추가
    • nvidia 에서도 받을수 있지만 다운로드 속도 이슈가 존재하여 conda-forge가 안정적임
1
conda config --append channels conda-forge
  1. cudatoolkit 설치
    • 원하는 버전의 cudotoolkit 설치
1
conda install cudatoolkit=[Version] -c conda-forge
  1. cudatoolkit-dev 설치
  • cuda Version에 따른 사용 채널 명
    • 11.x : conda-forge
    • 10.2 : trenta3
1
conda install cudatoolkit-dev=[Version] -c [Channel]

여기까지 진행하면 conda에서 설정되지 않았던 nvcc가 동작한다.
추가적으로 환경별로 다른버전의 cuda Version을 사용할 수 있다.

Functools.Partial


과제를 하다가 functools의 partial을 쓸 기회가 있었는데 오류를 뱉어서 나름대로 해결을 하고 정답지를 보니 작성한 코드가 달라서 한번 조사해보고 쓰는 글입니다.

Functools의 Partial에 대해 알아보자

  • functools Module의 내장 함수인 Partial은 기존에 존재하는 함수에 추가적인 인수를 지정하여 새로운 버전의 함수로 만들어주는 기능을 가지고 있다.

Partial의 예시

말로만 설명하면 이해하기 힘드니 코드와 같이 보자

다음과 같이 n진수를 10진수의 형태로 바꾸어 주는 함수가 있다고 하자

1
2
def to_int(num, base):
return int(num, base=base)

이때 특정한 수 2와 3을 Base로 하는 함수를 원한다고 할 때 다음과 같이 사용할 수 있다.

1
2
3
4
5
def two_to_int(num):
return to_int(num, base=2)

def three_to_int(num):
return to_int(num, base=3)

하지만 매번 특정한 수를 Base로 하는 함수를 이렇게 여러줄로 정의하면 코드의 줄도 길어지고 귀찮을수 있는데 이때 Partial을 사용하면 다음과 같이 함수를 새로 정의할 수 있다.

1
2
3
4
5
6
7
two_to_int = partial(to_int, base=2)
three_to_int = partial(to_int, base=3)

two_to_int("10")
2
three_to_int("120")
15

내부 구조

Partial 함수는 아래 코드와 같이 정의되어있다

여기서 2가지 방법으로 함수의 인자를 미리 설정할 수 있다.

  • partial(함수이름, 변수)
    • newfunc.args에 변수를 저장한다
  • partial(함수이름, 변수명=변수)
    • newfunc.keywords에 변수명이 Key, 변수가 value로 저장된다
    • 기존에 있는 변수를 변수명을 통해서 다시 지정할 때 그 변수의 입력위치가 중간에 존재할 경우 Error가 발생한다
1
2
3
4
5
6
7
8
def partial(func, /, *args, **keywords):
def newfunc(*fargs, **fkeywords):
newkeywords = {**keywords, **fkeywords}
return func(*args, *fargs, **newkeywords)
newfunc.func = func
newfunc.args = args
newfunc.keywords = keywords
return newfunc
  • 함수가 실행될때는 newfunc.args에 저장된 args, 함수에 입력되는 parameter, newfunc.keywords 순으로 순차적으로 입력된다
1
2
3
4
5
6
7
8
9
10
11
12
def tempfunc(one, two, three, four):
print(one, two, three, four)

a = partial(tempfunc, 1, 2)
a(5, 3)
output
1 2 5 3

a = partial(tempfunc, two=1)
a(5, 3, 2)
output
TypeError: tempfunc() got multiple values for argument 'two'

reference


12
cities = ["Seoul", "Busan", "Jeju"] 
iter_obj = iter(cities)
print(next(iter_obj))
print(next(iter_obj))
print(next(iter_obj))
next(iter_obj)
==============
output:
Seoul
Busan
Jeju
Error 발생 더이상 출력할 수 있는 원소가 없음

10.5 generator

1
2
3
4
5
6
7
8
def asterisk_test(a, b, **kargs):
print(kargs)
return a+b+sum(kargs.values())
print(asterisk_test(1, 2, three=3, four=4, five=5))
===================================================
output:
{'three': 3, 'four': 4, 'five': 5}
15

10.7 Asterisk

부스트 캠프 ai tech 1주 2일차 Python Basic for AI (5)


9. 데이터 구조

  • Stack & Queue
  • Tuple & Set
  • Dictionary
  • Collection

9.1 Stack & Queue

  • Stack
    • 나중에 넣은 데이터를 먼저 반환하도록 설계된 데이터 구조
    • LIFO (Last in First Out)
    • 입력을 Push, 출력을 Pop이라고 한다
    • python의 list는 기본적으로 Stack의 구조를 가진다
  • Queue
    • 먼저 넣은 데이터가 먼저 반환하도록 설계된 데이터 구조
    • FIFO (First in First Out)
    • 입력은 Push, 출력은 get 이라고 한다
    • 보통 python의 Dequeue를 사용한다.
  • 정해진 크기를 넘어갈 경우 overflow, element가 없는데 반환을 시킬경우 underflow라고 한다.

9.2 Tuple & Set

  • Tuple
    • 값의 변경이 불가능한 리스트
    • index로 접근해서 값을 수정하는것을 막는다
    • 정의 할 때 ( )를 사용한다
    • 리스트와 동일하게 (+, *)연산, Indexing, Slicing을 사용한다
    • 사용자의 실수에 의한 에러를 사전에 방지하기 위해 변경할 필요가 없는 데이터를 저장할 때 사용한다
1
2
3
t = (1, ) # 값이 1개인 Tuple은 반드시 ,를 붙여야 함
t + t # (1, 1)
t[0] = 2 # Error 발생함
  • Set
    • 값을 순서없이 저장, 중복을 허용하지 않는 자료형(확인필요)
    • set( )을 통하여 객체를 생성한다
    • set을 이용하여 다양한 집합연산이 가능하다
      1
      2
      3
      4
      5
      6
      7
      8
      s1 = set([1, 2, 3, 4, 5])
      s2 = set([1, 3, 5, 7, 9])
      s1.union(s2) # (1, 2, 3, 4, 5, 7, 9) 합집합
      s1 | s2 # (1, 2, 3, 4, 5, 7, 9) 합집합
      s1.intersection(s2) # (1, 3, 5) 교집합
      s1 & s2 # (1, 3, 5) 교집합
      s1.difference(s2) # (2, 4) 차집합
      s1 - s2 # (2, 4) 차집합

9.3 Dictionary

  • 데이터를 저장 할 때 구분지을수 있는 값(Key)를 함께 저장
  • Hash 구조
  • Key값을 활용하여 Value를 관리한다.
  • dict( )나 { }로 객체를 생성한다
1
2
3
4
5
6
7
8
9
10
number_dic = {'one': 1, 'two': 2, 'three': 3}
number_dic['one'] # 1, Key 값으로 value 출력 가능
country_code.items() # 데이터 출력
# dict_items([('one', 1), ('two', 2), ('three', 3)])
number_dic.keys() # key만 출력
# dict_keys(['one', 'two', 'three'])
number_dic.values() # value만 출력
# dict_values([1, 2, 3])
number_dic.get(1) # None, 아닐경우 None
number_dic.get('one') # 1, key가 존재할 경우 values 값을 return

9.4 Collections

  • Python Built-in 확장 모듈

  • 편의성, 실행 효율 등을 사용자에게 제공함

  • 자주 사용되는 deque, difaultdict, Counter에 대해서만 다룰것이다

  • deque

    • Stack과 Queue의 기능을 모두 지원하는 데이터 구조
    • List에 비해 효율적인 저장방식을 지원한다
      • popleft()등 삽입 삭제에 매우 효율적임
    • Linked List의 특성(rotate, reverse)을 지원한다
    • 기존 list 형태의 함수를 모두 지원함
      1
      2
      3
      4
      5
      from collections import deque
      q = deque()
      q.append(a) # [a]
      q.appendleft(b) # [b, a]
      q.popleft() # [a]
  • defaultdict

    • Dict type값에 기본값을 지정해서 key가 존재하지 않아도 기본값으로 찾아지는 기능을 가지고 있다
    • defaultdict(datatype) 으로 기본값의 자료형을 정하면서 dict객체를 생성할 수 있다
      1
      2
      3
      4
      from collections import defaultdict
      dic = defaultdict(int)
      dic['a'] += 1 # {'a': 1}
      dic['b'] -= 1 # {'a': 1, 'b': -1}
  • Counter

    • 시퀸스 type의 data element들의 갯수를 dict형태로 변환
      1
      2
      3
      from collections import Counter
      c = Counter([1, 3, 5, 3, 2, 4, 3])
      # Counter({1: 1, 3: 3, 5: 1, 2: 1, 4: 1})

부스트 캠프 ai tech 1주 2일차 Python Basic for AI (4)


8. 문자열(string)

  • char들이 저장되어있는 시퀸스 자료형
  • 기본적으로 list와 같은 형태로 데이터를 처리한다
    • Indexing, Slicing, +, * 연산은 리스트와 동일하게 수행한다

8.1 자주 사용하는 문자열 함수

함수명 기능
len(a) 문자열의 문자 개수를 반환
a.upper() 대문자로 변환
a.lower() 소문자로 변환
a.capitalize() 첫 문자를 대문자로 변환
a.strip(input)
a.rstrip(input)
a.lstrip(input)
좌우/우/좌 input을 없앰
a.split(input) input 기준으로 문자열을 나눠서 리스트로 반환
a.isdigit()
a.islower()
a.isupper()
문자열이 숫자/소문자/대문자인지 여부 반환
a.startswith(input)
a.endswith(input)
문자열이 input으로 시작/끝 나는 문자열 여부 반환
str.join(list) list의 원소들을 str로 연결해서 하나의 문자열로 나타낸다
단 list의 원소는 모두 문자열 type 이어야 한다

8.2 다양한표현

  • \ (백슬래쉬) : 특수하게 사용하는 문자열을 표현하기위해서 사용한다
    • 백슬래쉬를 표현하기 위해서는 \\ 두번 사용하면 된다.
  • \n : 줄바꿈을 의미하는 특수문자
  • \t : TAB
  • “””문자열””” : 줄바꿈도 자유롭게 입력 가능한 문자열 표현
  • r”문자열” : 특수문자를 무시하고 그대로 출력함
    1
    2
    print(r'이건 줄바꿈 기호입니다 \n')
    # output : 이건 줄바꿈 기호입니다 \n

부스트 캠프 ai tech 1주 2일차 Python Basic for AI (3)


6. Condition (조건문)

  • 조건에 따라 특정한 동작을 하게 하는 명령어
  • python 에서는 if, elif, else의 예약어를 사용한다
  • 조건을 나타내는 기준과 실행해야하는 명령으로 구성된다
  • 조건이 참일때만 실행한다
    1
    2
    3
    4
    5
    6
    7
    8
    if age <= 13:
    print('초등학생')
    elif age <= 16:
    print('중학생')
    elif age <= 19:
    print('고등학생')
    else:
    print('성인')
비교연산자 설명
x < y x가 y보다 작은지 검사
x > y x가 y보다 큰지 검사
x == y x와 y가 같은값인지 검사
x is y x와 y의 메모리 주소가 같은지 검사
x != y x와 y가 같은값인지 검사
x is not y x와 y의 메모리 주소가 같은지 검사
x >= y x가 y이상인지 검사
x <= y x가 y이하인지 검사
  • c언어에서는 0은 False, 1은 True를 나타내지만, python에서는 성립하지 않는다
  • 존재하면 참, 없으면 거짓으로 판단한다
  • and, or, not 논리키워드와도 같이 사용한다
    1
    2
    3
    if 1 # True
    if 0 # True
    if None # False

6.1 삼항연산자(Ternary operators)

  • 참과 거짓만 존재하는 결과를 한줄에 표현 할 수 있다.
    1
    2
    a = 1
    print('number' if isinstance(a, int) else 'not number')

    isinstance(var, datatype) -> boolean

    데이터의 타입을 판단하는 함수

7. 반복문

  • 정해진 동작을 반복적으로 수행하게 하는 명령문
  • for, while 명령 키워드가 존재한다

7.1 for 문

  • iterable 한 object의 원소의 갯수 만큼 반복시켜주는 반복문
  • range, enumerate등과 연계하여 사용이 가능하다
    1
    2
    3
    4
    5
    6
    for i in range(1, 10, 2):
    print(i) # 1, 3 ... 7 ,9
    for i in range(10, 1, -1):
    print(i) # 10, 9, ... , 2, 1
    for i, x in enumerate('apple'):
    print(i, x) # 0 a, 1 p, ... , 4 e

7.2 while 문

  • 조건을 만족하는 동안 반복적으로 명령을 수행한다
    1
    2
    3
    4
    5
    i = 0
    while i < 5:
    print(i)
    i += 1
    # output 0, 1, 2, 3, 4

7.3 반복문 제어

  • break : 특정 조건에서 가장 가까운 반복문을 종료한다
  • continue : 특정 조건에서 남은 명령을 skip 하고 다음 루프로 넘어간다
  • else : 반복조건이 만족하지 않은경우 반복 종료시 1회 수행한다.
    • break로 반복문에서 탈출할 경우에는 수행하지 않음

부스트 캠프 ai tech 1주 2일차 Python Basic for AI (2)

1일차 배운내용 2일차에 정리하는중…


4. Function(함수)

  • 어떤 일을 수행하는 논리적인 코드 단위
  • parameter, indentation(들여쓰기), return 등으로 구성된다
  • argument : 함수를 호출할 때 입력되는 파라미터들을 말한다
1
2
3
4
5
def im_function(im_parameter): #함수의 정의와 파라미터
im_return = im_parameter # 수행 내용
return im_return # 리턴값

result = im_function(im_argument)
  • 함수에 return 값이 존재하지 않을경우 함수는 None을 리턴한다

4.1 지역변수 & 전역변수

  • 지역변수(local variable) : 함수 내에서만 사용되는 변수
  • 전역변수(global variable) : 프로그램 전체에서 사용하는 변수
    • global을 사용하여 함수내에서 정의 할 수 있다.
1
2
3
4
5
6
def function(x):
global y
return x + y

y = 5
print(function(6)) # 11

4.2 재귀함수(recursive Function)

  • 자기자신을 호출하는 함수
  • 종료조건이 존재하여 종료조건을 만족시킬때 까지 스스로를 호출한다
  • python에서는 recursivelimit가 걸려있어서 따로 sys 모듈을 통해 한도를 늘려놓아야 한다.
  • 개인적으로 별로 안이용하고 싶음

4.3 Function type hints & Docstring

  • Function type hints
    python에서는 dynamic typinig 형식으로 작성하기 때문에 별도로 자료형을 적어두지 않기 때문에 처음 함수를 사용하는 사용자가 interface를 알기 어렵다는 단점이 있다.
    이를 해결하기 위해 type hints 기능을 제공한다.
    • parameter와 return의 type을 알려주는 type hints
1
2
def this_is_function(var_name: var_type) -> return_type:
pass
  • Docstring
    함수에 대한 상세 스펙(필요한 parameter, return, 수행하는 일 등등)을 사전에 작성한다.
    세개의 따옴표로 함수명 아래에 표시한다
    1
    2
    3
    4
    5
    6
    7
    8
    9
    def function(x):
    """
    this is docstring
    return parameter
    x : int
    =======
    return int
    """
    return x

4.4 python 가이드 라인

  • 함수는 가능하면 짧게 작성한다
  • 함수이름에 역할, 의도를 명확하게 나타낼 수 있도록 한다
  • 하나의 함수에는 유사한 역할을 하는 코드만 포함한다
  • parameter로 받은 값 자체를 바꾸지 않는다
  • 공통 코드나 복잡한 수식은 함수로 나타낸다
  • PEP8 참고해보자

5. input & print & fommatting

  • input 함수는 콘솔창에서 문자열을 입력받는 함수이다(string 형태로 받아옴)
  • print 함수는 입력받은 값을 문자열으로 출력한다
  • , 를 사용할 경우 print문이 공백을 사이에 두고 연결된다
    1
    2
    3
    print("name :")
    name = input() # input -> 규범
    print("Hello", name) # Hello 규범
  • formatting을 통해서 출력양식의 형식을 지정할 수 있다.
type 설명
%s 문자열(string)
%c 문자 1개(character)
%d 정수 (int 형)
%f 부동소수(float 형)
%o 8진수
%x 16진수
%% % 문자 자체
  • %n.m(datatype)

    • string : n개의 문자로 맞춘다(공백으로 채운다). m 자리수까지만 나타낸다(혼용 불가)
    • int : n개의 문자로 맞춘다(공백으로 채운다). m 은 사용불가
    • float : n개의 문자로 맞춘다(공백으로 채운다). 소숫점 m자리까지 나타낸다
  • Python 3.6 이후의 PEP8에 근거한 formatting

    1
    2
    3
    name = Jone
    age = 20
    print(f'Hello, {name}. I am {age}.') # Hello, Jone. I am 20.
  • 예전방식

    1
    2
    print('%s %s' % ('one', 'two')) # one two
    print('%d %d'.format(1, 1)) # one two