def fn(a) :
a의 타입이 무엇인지 몰라 버그 유발 가능
def fn(a: int) -> bool:
a가 정수형임을 알리고 리턴값이 true or false임을 알림
리스트 컴프리헨션 : 기존 리스트를 기반으로 새로운 리스트를 만들어내는 구문
[n*2 for n in range(1, 10+1) if n&2==1]
# [2,6,10,14,18]
#리스트 컴프리헨션을 사용하지 않는 경우
a=[]
for n in range(1, 10+1):
if n % 2 == 1:
a.append(n*2)
print(a)
# [2,6,10,14,18]
리스트외에도 딕셔너리등이 가능함
a={}
for key, value in original.items():
a[key]=value
#한줄로 표현 가능
a = {key: value for key, value in original.items()}
제너레이터 : 루프의 반복 동작을 제어할 수 있는 루틴
ex) 숫자 1억개를 만들어내 계산하는 프로그램
! 제너레이터가 없으면 메모리 어딘가에 1억개의 숫자를 보관해야함
제너레이터를 생성해두고 필요할때 언제든 숫자를 만들 수 있음
1억개 숫자중 100개만 사용하는 경우, 제너레이터를 사용하는 것이 나음
#함수의 리턴값은 제너레이터가 됨
def get_natural_number():
n = 0
#while true이므로 계속해서 값을 내보냄
while True:
n+=1
yield n
yield구문을 사용하면 제너레이터를 리턴할 수 있다.
(기존함수는 return 구문을 만나면 값을 리턴하고 함수의 동작을 종료함)
yield는 제너레이터가 여기까지 실행중이던 값을 내보낸다는 뜻
중간값을 리턴한 다음 함수는 종료되지 않고 끝까지 실행됨
g = get_natural_number()
for _ in range(0. 100):
print(next(g)) #next로 값을 추출 할 수 있다.
#1
#2
#.
#.
#.
#99
#100
여러 타입의 값을 하나의 함수에서 생성하는 것도 가능
def generator():
yield 1
yield 'string'
yield True
g = generator()
next(g) #1
next(g) #'string'
next(g) #True
range : 제너레이터의 방식을 활용하는 대표적인 함수
list(range(5))
#[0,1,2,3,4]
range(5)
#range(0, 5)
type(range(5))
#<class 'range'>
for i in range(5):
print(i, end=" ")
#0 1 2 3 4
range()는 range클래스를 리턴
for문에서는 내부적으로 제너레이터의 next를 호출하듯 숫자 생성
만약) 숫자가 100만개라면?
# 1번
a = [n for n in range(1000000)]
#2번
b = range(10000000)
len(a) #1000000
len(b) #1000000
len(a) == len(b) #True
a #range(0, 1000000) => 생성된 값이 담겨있음
b #<class 'range'> => 생성해야한다는 조건만 있음
#따라서 크기를 비교해보면
sys.getsizeof(a) #8697464
sys.getsizeof(b) #48 => 1억개라도 메모리 점유율은 동일함, 생성조건만 보관하고 있기 때문이다.
#인덱스로 접근 시에는 바로 생성하도록 구현되어 있음
b[999] #999
enumerate : "열거하다" 여러가지 자료형을 인덱스를 포함한 enumerate객체로 리턴함
a = [1,2,3,2,45,2,5]
a #[1,2,3,2,45,2,5]
enumerate(a)
#<enumerate object at ~~~>
#list로 결과를 추출할 경우, 인덱스를 자동으로 부여해줌
list(enumerate(a))
#[(0,1), (1,2), (2,3), (3,2), (4,45), (5,2), (6,5)]
#인덱스와 값을 함께 출력??
a = ['a1', 'b2', 'c3']
#1번 => range사용
for i in range(len(a)):
print(i, a[i])
#2번 => 인덱스 위한 변수 따로 선언
i = 0
for v in a:
print(i, v)
i += 1
#3번 => 인덱스와 값 함께 처리
for i, v in enumerate(a):
i += 1
나눗셈
// => 정수형으로 유지
5/3
#1.66666666666666667
5//3
#1
5//3 = int(5/3)
#몫과 나머지 한번에 구함
divmod(5, 3)
#(1, 2)
print
콤마로 구분
print('A1', 'B2')
#>>A1 B2
파라미터로 구분자 지정
print('A1', 'B2', sep=',')
#구분자를 ,로 지정
#>>A1, B2
print 함수는 항상 줄바꿈을 한다. 따라서 루프의 값을 반복적으로 출력하려면 end 파라미터를 공백처리한다.
print('aa', end =' ')
print('bb')
#>> aa bb
리스트 출력시 join으로 묶어서 처리
a = ['A', 'B']
print(' '.join(a))
#>>A B
문자열 함께 출력
idx = 1
fruit = "Apple"
print('{0}: {1}'.format(idx + 1, fruit))
#>>2: Apple
#인덱스 생략도 가능
idx = 1
fruit = "Apple"
print('{}: {}'.format(idx + 1, fruit))
#>>2: Apple
f-string(formated string literal)
print(f'{idx+1}: {fruit}')
#>>2: Apple
pass
class MyClass(object):
def method_a(self):
def method_b(self):
print("Method B")
c = MyClass()
위 코드는 실행되지 않는다.
method_a()가 아무런 처리를 하지 않았기 때문에 method_b()에서 오류가 발생한다.
pass는 이런 오류를 막는다.
class MyClass(object):
def method_a(self):
#pass 삽입
pass
def method_b(self):
print("Method B")
c = MyClass()
pass는 null연산으로 아무 작업도 하지 않는다. 따라서 인덴트 오류같은 불필요한 오류를 방지한다.
pass를 사용하여 mockup 인터페이스부터 구현한 다음 추후 구현을 할 수 있게 된다.
locals
locals()는 로컬 심볼 테이블 딕셔너리를 가져오는 메소드이다.
로컬에 선언된 모든 변수를 조회할 수 있다.
...
import pprint
pprint.pprint(locals())
...
pprint로 출력하게 되면 클래스 메소드 내부의 모든 로컬변수를 출력해준다.
{'num':[2,7,11,15].
'pprint': >module 'pprint' from '/user/lib/python3.8/pprint.py'>,
'self':<__main__.Solution object at 0x~~~~>,
'target; : 9'}
int
숫자 정수형 int만 제공
int가 충분하지 않으면 자동으로 long 타입으로 변환됨
bool은 논리 자료형이지만 내부적으로 int로 처리된다.
Ture == 1
>>True
False == 0
>>True
매핑
키와 자료형으로 구성된 복합 자료형
유일한 매핑 자료형은 딕셔너리이다.
집합
set은 중복된 값을 갖지 않는 자료형이다.
입력순서가 유지되지 않으며 중복된 값이 있을 경우 하나의 값만 유지한다.
a=set()
a
>>set()
type(a)
>><class 'set'>
{} 중괄호를 사용하여 선언함
a={'a','b','c'}
시퀀스
특정 대상의 순서있는 나열
str은 문자의 순서 있는 나열로 문자열을 이루는 자료형이고, list는 다양한 값들을 배열 형태의 순서있는 나열로 구성하는 자료형이다.
시퀀스는 불변(immutable)과 가변(mutable)로 구분한다.
불변 : 값을 변경할 수 없다. => str, tuple, bytes
a='abc' #abc할당
a='def' #def할당
type(a)
>><class 'str'>
a 변수에 처음 abc가 할당되고, 이후 다른 str타입인 def를 다시 참조했다.
a='abc'
id('abc')
>>4317530408
id(a)
>>4317530408
a='def'
id('def')
>>4318831648
id(a)
>>4318831648
각 메모리 주소를 보면 참조하는 주소가 바뀐 것을 알 수 있다.
변경되려면 다음과 같은 할당자가 처리되어야한다.
a[1]='d'
>> 오류 발생
하지만 오류가 발생한다.
가변 : 값을 변경할 수 있다. => list
list는 값을 추가/삭제할 수 있는 동적 배열이다.