시퀀스
시퀀스 기본
파이썬에는 3가지 시퀀스 자료형이 있다.
- 문자열 : 문자열(string) ‘Hello’는 문자(character)들의 시퀀스이다.
- 리스트 : [1, 4, 5]
- 튜플 : (’GOOD’, 100, 121.12)
모든 시퀀스는 순서가 유지되고, 정수로 인덱싱하며 길이가 있다.
자료형 구분 정리
컨테이너와 플랫
컨테이너(container): 서로 다른 자료형을 하나의 컬렉션에 담을 수 있는 것([list, tuple, collections.deque])
플랫(Flat): 한 개의 자료형만 담을 수 있는 것([str, bytes, bytearray, array.array, memoryview])
가변 vs 불변형
가변형(list, bytearray, array.array, memoryview, deque)
불변형(tuple, str, bytes)
참고 : ord, chr, map 함수
ord 함수와 chr함수
ord 함수는 char형을 받아와서 unicode값을 반환한다. chr 함수는 이와 반대로 유니코드 값을 받아와서 문자로 변경해준다.
파이썬 map 함수
첫 번째 인자는 함수이고, 두번째 인자는 반복할 수 있는 자료형(리스트, 튜플 등)이 온다. 두번째 인자로 들어온 반복 자료형의 원소를 하나씩 첫 번째 인자의 함수에 넣어서 실행하는 방식으로 작동한다.
map 함수의 반환값은 map 객체이기 때문에 list, tuple 등으로 변환시켜주는 것이 편하다.
import math # math.ceil 함수 사용
# 예제1) 리스트의 값을 정수 타입으로 변환
result1 = list(map(int, [1.1, 2.2, 3.3, 4.4, 5.5]))
print(f'map(int, 리스트) : {result1}')
# 예제2) 리스트 값 제곱
def func_pow(x):
return pow(x, 5) # x 의 5 제곱을 반환
result2 = list(map(func_pow, [1, 2, 3, 4, 5]))
print(f'map(func_pow, 리스트) : {result2}')
# 예제3) 리스트 값 소수점 올림
result3 = list(map(math.ceil, [1.1, 2.2, 3.3, 4.4, 5.5, 6.6]))
print(f'map(func_ceil, 리스트) : {result3}')
Generator
제너레이터는 시퀀스를 생성해주는 함수이다. 한 번에 한 개의 항목만 생성하여 메모리에 유지가 되지 않기 때문에 성능면에서 단순한 반복문보다 효율적이다. 예를 들어 [1, …, 1000000]의 리스트의 각 원소에 숫자를 1씩 더하기 위해서는 일단 이 리스트를 변수로 선언하고 for문을 사용해야한다. 이렇게 되면 리스트의 모든 원소를 갖는 변수가 메모리에 저장되므로 리스트의 크기만큼 메모리의 공간을 차지하게 되어 낭비가 발생한다. 하지만 generator는 연산이 필요한 그 순간의 데이터만 저장하기 때문에 메모리 낭비가 적다.
iter : 어떤 자료형, 예를 들어 list에 dir(list)로 조회했을 때, __iter__가 존재하면 해당 자료형은 iterator를 갖고 있어서 반복이 가능하다는 것을 뜻한다.
제너레이터의 생성은 list comprehension 구문을 소괄호()로 감싸주는 것으로 가능하다.
list = [ord(s) for s in chars] #list comprehension
tuple_g = (ord(s) for s in chars) #generator
type(tuple_g) # <class 'generator'>
next(tuple_g) # 43 (맨 처음 값)
예제
print(('%s' %c + str(n) for c in ['A', 'B', 'C', 'D'] for n in range(1,21)))
#<generator object <genexpr> at 0x00012....
for s in ('%s' %c + str(n) for c in ['A', 'B', 'C', 'D'] for n in range(1,21)):
print(s)
"""
A1
A2
...
D20
"""
array
array는 자유롭게 변경될 수 있는 list에 비해서 크기가 고정되고, 원소의 타입도 고정된 정적 타입의 자료형이기 때문에 수치연산이나 고속의 처리가 필요한(numPy 패키지 등) 상황에 사용한다.
array_g = array.array('I', (ord(s) for s in chars))
print(type(array_g)) # <class array.array>
print(array_g.tolist()) #[43, 95, 56, ...]
깊은 복사와 얕은 복사
for문을 이용하여 list를 반복 생성하면 깊은 복사처럼 각 list의 id 값들이 개별적으로 생성되지만, *로 list를 반복하면 얕은 복사가 실행되어 주소값만 복사하여 각 list가 같은 객체를 바라보게 된다. 중요한 데이터가 이런 방식으로 같은 객체로 복사하면 치명적일 수 있으므로 주의해야한다. 애매할 때는 id() 함수를 이용하여 확인하는 것이 권장된다.
list1 = [['a'] * 3 for _ in range(5)]
list2 = [['a'] * 3] * 4
list1[0][0] = 'b'
list2[0][0] = 'b'
print(list1) # [['b', 'a', 'a'], ['a', 'a', 'a'], ['a', 'a', 'a']]
print(list2) # [['b', 'a', 'a'], ['b', 'a', 'a'], ['b', 'a', 'a']]
packing과 unpacking
unpacking
(a, b) = (b, a) 도 packing된 튜플을 unpacking한 뒤 다시 packing하는 형태이다.
예시 : divmod
첫 번째 인자를 두 번째 인자로 나눈 몫과 나머지를 튜플 형태로 반환한다. 두 개의 인자를 받는데, 하나의 튜플로 전달하고 싶다면 튜플 앞에 *을 붙여서 unpacking이 되도록 해줘야한다. 함수 자체에 *을 써주면 결과값이 unpacking된다.
print(divmod(100, 9)) #(11,1)
print(divmod((100, 9))) #Type error
print(divmod(*(100,9))) #(11,1)
print(*divmod(100, 9)) #11 1
range packing
x, y, *rest = range(10)
print(x, y, rest) #1 2 [3,4,5,6,7,8,9]
mutable vs immutable
list는 연산자의 활용에 따라서 주소값이 동일하거나 달라지지만, tuple은 변경이 불가하므로 항상 주소값이 달라진다.
l = (10, 20)
m = [30, 40]
print(l, id(l)) #(10, 20) 1929188125912(id값)
print(m, id(m)) #[30, 40] 1902190521850(id값)
l = l * 2
m = m * 2
print(l, id(l)) #(10, 20, 10, 20) 1251251623547(id값)
print(m, id(m)) #[30, 40, 30, 40] 1251364894589(id값)
l *= 2
m *= 2
print(l, id(l)) #(10, 20, 10, 20, 10, 20, 10, 20) 1924151902122(id값, 새로 지정)
print(m, id(m)) #[30, 40, 30, 40, 30, 40, 30, 40] 1251364894589(id값, 위와 동일)
sort vs sorted
sorted는 정렬 후 새로운 객체를 반환하고, sort는 기존 객체를 정렬하여 변경한다. sorted 함수의 인자는 차례대로 reversed, key={함수}를 받는다.
animals = ['crocodile', 'dog', 'horse', 'sheep', 'tiger', 'giraffe', 'cat']
#sort와 sorted의 문법 차이
#animals.sort()
#sorted(animals, ...)
print(sorted(animals, key=len))
#길이별 오름차순으로 정렬한다.
#['dog', 'cat', 'horse', 'sheep', 'tiger', 'giraffe', 'crocodile']
print(sorted(animals, key=lambda x: x[-1]))
#각 원소의 맨 뒤 알파벳 오름차순으로 정렬한다.
#['crocodile', 'horse', 'giraffe', 'dog', 'sheep', 'tiger', 'cat']
참조
1. 인프런 강의 - 우리를 위한 프로그래밍 : 파이썬 중급 (Inflearn Original)
'Programming-[Backend] > Python' 카테고리의 다른 글
파이썬 중급 - 5. 고위 함수(Higher Order Function), 클로저(Closure) 기본 (0) | 2022.07.17 |
---|---|
파이썬 중급 - 4. 해시테이블(Dictionary), Set (0) | 2022.07.17 |
파이썬 중급 - 2. 매직 메서드, namedtuple (0) | 2022.07.17 |
파이썬 중급 - 1. 클래스와 메서드 (0) | 2022.07.17 |
Python 라이브러리 실행 에러 : Windows 환경에서 pip install 정확히 하기(black, isort 실행 문제) (2) | 2022.07.08 |