Ai tech Day3

Lee·2021년 1월 20일
0

Python data structure

스택 (Stack)
큐 (Queue)
튜플 (Tuple)
집합 (Set)
사전 (Dictionary)
Collection 모듈



Stack (스택)

나중에 넣은 데이터를 먼저 반환하도록 설계된 메모리 구조

  • Last In First Out (LIFO)
  • Data의 입력을 Push, 출력을 pop이라고 한다.
  • List를 사용하여 스택 구조를 구현한다.
  • push를 append(), pop을 pop()를 사용한다.
a = [1,2,3,4,5]
a.append(10)
a.append(20)
a.pop() # 20 출력
# 20
a.pop() # 10 출력
# 10


Queue (큐)

먼저 넣은 데이터를 먼저 반환하도록 설계된 메모리 구조

  • First In First Out (FIFO
  • Stack과 반대되는 개념
  • List 사용하여 큐 구조를 구현한다.
  • put을 append(), get을 pop(0)를 사용한다.
a = [1,2,3,4,5]
a.append(10)
a.append(20)
a.pop(0) # 1 출력
# 1
a.pop(0) # 2 출력
# 2


Tuple (튜플)

값의 변경이 불가능한 List

  • 선언 시 “[ ]” 가 아닌 “( )”를 사용한다.
  • List의 연산, 인덱싱, 슬라이싱 등을 동일하게 사용한다.
  • 함수의 반환 값 등 사용자의 실수에 의한 에러를 사전에 방지하기 위해 사용한다.
t = (1,2,3)
print (t + t , t * 2) # (1, 2, 3, 1, 2, 3) (1, 2, 3, 1, 2, 3)
# (1, 2, 3, 1, 2, 3) (1, 2, 3, 1, 2, 3)
len(t) # 3
# 3

t[1] = 5 # Error 발생
# Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
# TypeError: 'tuple' object does not support item assignment
t = (1) # 일반정수로 인식
# 1
t = (1, ) # 값이 하나인 Tuple은 반드시 "," 를 붙여야 함
(1,)


Set (집합)

값을 순서없이 저장, 중복 불허 하는 자료형

  • set() 객체 선언을 이용하여 객체 생성한다.
s = set([1,2,3,1,2,3]) # set 함수를 사용 1,2,3을 집합 객체 생성 , a = {1,2,3,4,5} 도 가능
s
# {1, 2, 3}
s.add(1) # 한 원소 1만 추가, 추가, 중복불허로 추가 되지 않음
s
# {1, 2, 3}
s.remove(1) # 1 삭제
s
# {2, 3}
s.update([1,4,5,6,7]) # [1,4,5,6,7] 추가
s
# {1, 2, 3, 4, 5, 6, 7}
s.discard(3) # 3 삭제
s
# {1, 2, 4, 5, 6, 7}
s.clear() # 모든 원소 삭제
  • 수학에서 활용하는 다양한 집합연산이 가능하다.
s1 = set([1,2,3,4,5])
s2 = set([3,4,5,6,7])
s1.union(s2) # s1 과 s2의 합집합
# {1, 2, 3, 4, 5, 6, 7}
s1 | s2 # set([1, 2, 3, 4, 5, 6, 7])
# {1, 2, 3, 4, 5, 6, 7}
s1.intersection(s2) # s1 과 s2의 교집합
# {3, 4, 5}
s1 & s2 # set([3, 4, 5])
# {3, 4, 5}
s1.difference(s2) # s1 과 s2의 차집합
# {1, 2}
s1 - s2 # set([1, 2])
# {1, 2}


Dictionary (사전)

데이터를 저장 할 때 구분 지을 수 있는 값(key)을 함께 저장하는 자료형

  • 구분을 위한 데이터 고유 값을 Identifier 또는 Key라고 한다.
  • Key 값을 활용하여, 데이터 값(Value)를 관리한다.
  • key와 value가 매칭되어 key로 value를 검색한다.
  • {Key1 : Value1, Key2 : Value2, Key3 : Value3} 형태
country_code = {} # Dict 생성, country_code = dict() 도 가능
country_code = {"America": 1, "Korea": 82, "China": 86, "Japan": 81}
country_code
# {'America': 1, 'China': 86, 'Korea': 82, 'Japan': 81}
country_code.items() # Dict 데이터 출력
Dict_items([('America', 1), ('China', 86), ('Korea', 82), ('Japan', 81)])
country_code.keys() # Dict 키 값만 출력
Dict_keys(["America", "China", "Korea", "Japan"])
country_code["German"]= 49 # Dict 추가
country_code
# {'America': 1, 'German': 49, 'China': 86, 'Korea': 82, 'Japan': 81}
country_code.values() # Dict Value만 출력
# dict_values([1, 49, 86, 82, 81])
"Korea" in country_code.keys() # Key값에 "Korea"가 있는지 확인
# True
82 in country_code.values() # Value값에 82가 있는지 확인
# True


Collections

List, Tuple, Dict에 대한 Python Built-in 확장 자료 구조(모듈)

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

deque

  • Stack과 Queue를 지원하는 모듈
  • List에 비해 효율적인(빠른) 자료 저장 방식을 지원한다.
    -> 효율적 메모리 구조로 처리 속도가 빠르다.
from collections import deque

deque_list = deque()
def func1():
    for i in range(100):
        for i in range(100):
            deque_list.append(i)
            deque_list.pop()
            
%timeit func1() # Jupyter Notebook에서 제공하는 함수


def func2():
    just_list = []
    for i in range(100):
        for i in range(100):
            just_list.append(i)
            just_list.pop()
            
%timeit func2()
  • rotate, reverse등 Linked List의 특성을 지원한다.
  • 기존 List 형태의 함수를 모두 지원한다.
from collections import deque

deque_list = deque()
for i in range(5):
    deque_list.append(i)
print(deque_list)
deque_list.appendleft(10)
print(deque_list)

deque_list.rotate(2)
print(deque_list)
deque_list.rotate(2)
print(deque_list)
print(deque(reversed(deque_list)))
deque_list.extend([5, 6, 7])
print(deque_list)
deque_list.extendleft([5, 6, 7])
print(deque_list)

OrderedDict

데이터를 입력한 순서대로 반환하는 dict 자료형

d = {}
d['x'] = 100
d['y'] = 200
d['z'] = 300
d['l'] = 500

for k, v in d.items():
    print(k, v)


from collections import OrderedDict

d = OrderedDict()
d['x'] = 100
d['y'] = 200
d['z'] = 300
d['l'] = 500

for k, v in d.items():
    print(k, v)
  • Dict type의 값을, value 또는 key 값으로 정렬할 때 사용한다.
for k, v in OrderedDict(sorted(d.items(), key=lambda t: t[0])).items():
    print(k, v)
    
for k, v in OrderedDict(sorted(d.items(), key=lambda t: t[1])).items():
    print(k, v)

defaultdict

dict type의 값(value)에 기본 값을 지정하고, 신규값 생성시 사용하는 dict

d = dict()
print(d['first']) # Error 발생



from collections import defaultdict

d = defaultdict(object) # Default dictionary를 생성
d = defaultdict(lambda: 0) # Default 값을 0으로 설정합
print(d["first"])

Conuter

Sequence type data의 element 갯수를 반환하는 dict 자료형

from collections import Counter

c = Counter()
c = Counter('gallahad')
print(c)
# Counter({'a': 3, 'l': 2, 'g': 1, 'h': 1, 'd': 1})
  • Dict type, keyword parameter 등도 모두 처리 가능하다.
c = Counter({'red': 4, 'blue': 2})
print(c)
print(list(c.elements()))
# Counter({'red': 4, 'blue': 2})
# ['red', 'red', 'red', 'red', 'blue', 'blue']

c = Counter(cats = 4, dogs = 8)
print(c)
print(list(c.elements()))
# Counter({'dogs': 8, 'cats': 4})
# ['cats', 'cats', 'cats', 'cats', 'dogs', 'dogs', 'dogs', 'dogs', 'dogs', 'dogs', 'dogs', 'dogs']
  • Set의 연산들을 지원한다.
c = Counter(a = 4, b = 2, c = 0, d = -2)
d = Counter(a = 1, b = 2, c = 3, d = 4)
print(c + d)
# Counter({'a': 5, 'b': 4, 'c': 3, 'd': 2})
print(c & d)
# Counter({'b': 2, 'a': 1})
print(c | d)
# Counter({'a': 4, 'd': 4, 'c': 3, 'b': 2})
c.subtract(d) # c - d
print(c)
# Counter({'a': 3, 'b': 0, 'c': -3, 'd': -6})


nametuple

Tuple 형태로 Data 구조체를 저장하는 자료형

  • 저장되는 data의 variable을 사전에 지정해서 저장함
from collections import namedtuple

Point = namedtuple('Point', ['x', 'y'])
p = Point(11, y=22)
print(p[0] + p[1])
x, y = p
print(x, y)
print(p.x + p.y)
print(Point(x=11, y=22))






Pythonic code

Python 스타일의 코딩 기법

  • 파이썬 특유의 문법을 활용하여 효율적으로 코드를 표현한다.
  • 그러나 더 이상 파이썬 특유는 아니고, 많은 언어들이 서로의 장점을 채용 중이다.
  • 고급 코드를 작성 할 수록 더 많이 필요해진다. (코드에 대한 이해도를 높인다)
colors = ['red', 'blue', 'green', 'yellow']
result = ''
for s in colors:
    result += s
    
colors = ['red', 'blue', 'green', 'yellow']
result = ''.join(colors)
result


split

string type의 값을 “기준값”으로 나눠서 List 형태로 변환

items = 'zero one two three'.split() # 빈칸을 기준으로 문자열 나누기
print (items)
# ['zero', 'one', 'two', 'three']
example = 'python,java,javascript' # ","을 기준으로 문자열 나누기
example.split(",")
# ['python', ‘java', 'javascript']
a, b, c = example.split(",")
# 리스트에 있는 각 값을 a,b,c 변수로 unpacking
example = ‘teamlab.technology.io'
subdomain, domain, tld = example.split('.')
# "."을 기준으로 문자열 나누기 → Unpacking


join

String으로 구성된 list를 합쳐 하나의 string으로 반환

colors = ['red', 'blue', 'green', 'yellow']
result = ''.join(colors)
result
# 'redbluegreenyellow'
result = ' '.join(colors) # 연결 시 빈칸 1칸으로 연결
result
# 'red blue green yellow'
result = ', '.join(colors) # 연결 시 ", "으로 연결
result
# 'red, blue, green, yellow'
result = '-'.join(colors) # 연결 시 "-"으로 연결
result
# 'red-blue-green-yellow'


List Comprehension

기존 List를 사용하여 간단히 다른 List를 만드는 기법

  • 포괄적인 List, 포함되는 리스트라는 의미로 사용된다.
  • 파이썬에서 가장 많이 사용되는 기법 중 하나이다.
  • 일반적으로 for + append 보다 속도가 빠르다.
result = []
for i in range(10):
    result.append(i)
result
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
result = [i for i in range(10)]
result
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
result = [i for i in range(10) if i % 2 == 0]
result
# [0, 2, 4, 6, 8]
words = 'The quick brown fox jumps over the lazy dog'.split()
# 문장을 빈칸 기준으로 나눠 list로 변환.
# a ~ z 까지를 모두 포함하는 문장으로, 자주 사용된다.
print (words)
# ['The', 'quick', 'brown', 'fox', 'jumps', 'over', 'the', 'lazy', 'dog']
stuff = [[w.upper(), w.lower(), len(w)] for w in words]
# list의 각 elemente들을 대문자, 소문자, 길이로 변환하여 two dimensional list로 변환
for i in stuff:
    print (i)
# ['The', 'quick', 'brown', 'fox', 'jumps', 'over', 'the', 'lazy', 'dog']
# ['THE', 'the', 3]
# ['QUICK', 'quick', 5]
# ['BROWN', 'brown', 5]
# ['FOX', 'fox', 3]
# ['JUMPS', 'jumps', 5]
# ['OVER', 'over', 4]
# ['THE', 'the', 3]
# ['LAZY', 'lazy', 4]
# ['DOG', 'dog', 3]
  • 일반적으로 for 문은 순차적으로 실행되나 차원이 존재하면 가장 아래 차원의 for문 부터 실행된다.
case_1 = ["A","B","C"]
case_2 = ["D","E","A"]
result = [i+j for i in case_1 for j in case_2]
result
# ['AD', 'AE', 'AA', 'BD', 'BE', 'BA', 'CD', 'CE', 'CA']
result = [ [i+j for i in case_1] for j in case_2]
result
# [['AD', 'BD', 'CD'], ['AE', 'BE', 'CE'], ['AA', 'BA', 'CA']]


eumerate

list의 element를 추출할 때 번호를 붙여서 추출

for i, v in enumerate(['tic', 'tac', 'toe']):
# list의 있는 index와 값을 unpacking
    print (i, v)
# 0 tic
# 1 tac
# 2 toe

mylist = ['a', 'b', 'c', 'd']
list(enumerate(mylist)) # list의 있는 index와 값을 unpacking하여 list로 저장
# [(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd')]


zip

두 개의 list의 값을 병렬적으로 추출

alist = ['a1', 'a2', 'a3']
blist = ['b1', 'b2', 'b3']
for a, b in zip(alist, blist): # 병렬적으로 값을 추출
    print (a,b)
# a1 b1
# a2 b2
# a3 b3

a,b,c = zip((1,2,3),(10,20,30),(100,200,300)) #각 tuple의 같은 index 끼리 묶음
# (1, 10, 100) (2, 20, 200) (3, 30, 300)
[sum(x) for x in zip((1,2,3), (10,20,30), (100,200,300))]
# 각 Tuple 같은 index를 묶어 합을 list로 변환
# [111, 222, 333]
alist = ['a1', 'a2', 'a3']
blist = ['b1', 'b2', 'b3']

for i, (a, b) in enumerate(zip(alist, blist)):
    print (i, a, b) # index alist[index] blist[index] 표시
# 0 a1 b1
# 1 a2 b2
# 2 a3 b3


lambda

함수 이름 없이, 함수처럼 쓸 수 있는 익명 함수

def f(x, y):
    return x + y
    print(f(1, 4))


f = lambda x, y: x + y
print(f(1, 4))
  • PEP 8에서는 lambda의 사용을 권장하지 않는다고 한다.
# Yes
def f(x): return 2*x

# No
f = lambda x: 2*x
  • Problemes
    • 문법이 어렵고, 테스트도 어렵고, 문서화 docstring 지원이 미비하다.
    • 코드 해석이 어렵다, 이름이 존재하지 않는 함수가 출현한다.


map

list에 똑같은 함수를 적용

  • python3 는 iteration을 생성해서 list을 붙여줘야 list로 사용가능하다.
  • 실행시점의 값을 생성해서 메모리 효율적이다.
ex = [1,2,3,4,5]
f = lambda x, y: x + y
print(list(map(f, ex, ex)))

list(map(lambda x: x ** 2 if x % 2 == 0 else x, ex))


reduce

map function과 달리 list에 똑같은 함수를 적용해서 통합

from functools import reduce
print(reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]))


iterable object

Sequence형 자료형에서 데이터를 순서대로 추출하는 object

for city in ["Seoul", "Busan", "Pohang"]:
    print(city, end = "\t")
for language in ("Python", "C", "Java"):
    print(language, end = "\t")
for char in "Python is easy":
    print(char, end = " ")
  • 내부적 구현으로 __iter__ 와 __next__ 가 사용된다.
  • iter() 와 next() 함수로 iterable 객체를 iterator object로 사용한다.
cities = ["Seoul", "Busan", "Jeju"]
iter_obj = iter(cities)
print(next(iter_obj))
print(next(iter_obj))
print(next(iter_obj))
next(iter_obj)


generator

iterable object를 특수한 형태로 사용해주는 함수

  • element가 사용되는 시점에 값을 메모리에 반환한다.
    -> yield를 사용해 한번에 하나의 element만 반환한다.
def general_list(value):
    result = []
    for i in range(value):
        result.append(i)
    return result
    
    
def geneartor_list(value):
    result = []
    for i in range(value):
        yield i
  • list comprehension과 유사한 형태로 generator형태의 list를 생성한다.
  • generator expression 이라는 이름으로도 부른다.
  • [ ] 대신 ( ) 를 사용하여 표현
gen_ex = (n*n for n in range(500))
print(type(g))
  • 일반적인 iterator는 generator에 반해 훨씬 큰 메모리 용량을 사용한다.
from sys import getsizeof
gen_ex = (n*n for n in range(500))
print(getsizeof(gen_ex))
# 112
print(getsizeof(list(gen_ex)))
# 4568
list_ex = [n*n for n in range(500)]
print(getsizeof(list_ex))
# 4264
  • list 타입의 데이터를 반환해주는 함수는 generator로 만든다.
  • 읽기 쉬운 장점이 있다.
  • 중간 과정에서 loop이 중단될 수 있을 때 쓴다.
  • 큰 데이터를 처리할 때는 generator expression을 고려한다.
    -> 데이터가 커도 처리의 어려움이 없다.
  • 파일 데이터를 처리할 때도 generator를 쓸 수 있다.


function passing arguments

함수에 입력되는 arguments의 다양한 형태

1. Keyword arguments

  • 함수에 입력되는 parameter의 변수명을 사용하고, arguments를 넘긴다.
def print_somthing(my_name, your_name):
    print("Hello {0}, My name is {1}".format(your_name, my_name))
    
print_somthing("Sungchul", "TEAMLAB")
print_somthing(your_name="TEAMLAB", my_name="Sungchul")

2. Default arguments

-> parameter의 값을 입력하지 않는 경우 기본값을 출력한다.

def print_somthing_2(my_name, your_name="TEAMLAB"):
    print("Hello {0}, My name is {1}".format(your_name, my_name))
    
print_somthing_2("Sungchul", "TEAMLAB")
print_somthing_2("Sungchul"

3. Variable-length arguments

개수가 정해지지 않은 변수를 함수의 parameter로 사용하는 법

  • Asterisk(*) 기호를 사용하여 함수의 parameter를 표시한다.
  • Keyword arguments와 함께, argument 추가가 가능하다.
    -> 일반적으로 *args를 변수명으로 사용한다.
  • 기존 parameter 이후에 나오는 값을 tuple로 저장한다.
    -> 입력된 값은 tuple type으로 사용할 수 있다.
  • 가변인자는 오직 한 개만, 맨 마지막 parameter 위치에 사용가능하다.
  • keyword variable과 동시에 쓸 수 없다.
def asterisk_test(a, b, *args):
    return a + b + sum(args)
    
print(asterisk_test(1, 2, 3, 4, 5))

4. Keyword variable-length

Parameter 이름을 따로 지정하지 않고 입력하는 방법

  • asterisk(*) 두개를 사용하여 함수의 parameter를 표시한다.
  • 입력된 값은 dict type으로 사용할 수 있다.
  • 가변인자는 오직 한 개만, 기존 가변인자 다음에 사용한다.
def kwargs_test_1(**kwargs):
    print(kwargs)
    
def kwargs_test_2(**kwargs):
    print(kwargs)
    print("First value is {first}".format(**kwargs))
    print("Second value is {second}".format(**kwargs))
    print("Third value is {third}".format(**kwargs))
    
def kwargs_test_3(one,two,*args,**kwargs):
    print(one+two+sum(args))
    print(kwargs)
    
kwargs_test_3(3,4,5,6,7,8,9, first=3, second=4, third=5)


Asterisk

*

  • 단순 곱셈, 제곱연산, 가변 인자 활용 등 다양하게 사용된다.
  • tuple, dict 등 자료형에 들어가 있는 값을 unpacking 한다.
a, b, c = ([1, 2], [3, 4], [5, 6])
print(a, b, c)
# [1, 2] [3, 4] [5, 6]
data = ([1, 2], [3, 4], [5, 6])
print(*data)
# [1, 2] [3, 4] [5, 6]
  • 함수의 입력값, zip 등에 유용하게 사용가능하다.
def asterisk_test(a, *args):
    print(a, args)
    print(type(args))
    
asterisk_test(1, *(2,3,4,5,6))


def asterisk_test(a, args):
    print(a,*args)
    print(type(args))
    
asterisk_test(1, (2,3,4,5,6))
def asterisk_test(a, b, c, d,):
    print(a, b, c, d)
    
data = {"b":1 , "c":2, "d":3}
asterisk_test(10, **data)
profile
초보 개발자입니다

0개의 댓글

관련 채용 정보