[TOC]
데이터 구조
데이터 구조
- 데이터에 편리하게 접근하고, 변경하기 위해 데이터를 저장하거나 조작하는 방법
- 순서가 있는 데이터 구조
- 문자열
- 리스트
- 순서가 없는 데이터 구조
- 세트
- 딕셔너리
문자열
특징
- 변경할 수 없고(immutable)
- 순서가 있고(ordered)
- 순회 가능함(iterable)
# Immutable?
a = 'my string'
a[-1] = '!'
=> TypeError
문자열 슬라이싱
- 다음과 같이, 특정 문자열을 뒤집을 때 유용하게 사용 가능
s = 'abcd'
s[::-1]
=> dcba
문자열 관련 메서드
문자열 조회/탐색
.find()
- 문자열의 첫 번째 위치를 반환함
- 없으면 -1을 반환
# 형식
str.find(x)
# 예시
'apple'.find('p')
=> 1
'apple'.find('k')
=> -1
.index()
- 문자열의 첫 번째 위치를 반환
- 없으면 오류 발생
```python
# 형식
str.index(x)
# 예시
'apple'.index('p')
=> 1
'apple'.index('k')
=> ValueError
```.replace()
- 바꿀 대상의 글자를 새로운 글자로 바꿔서 반환
- count를 지정하면, 해당 개수만큼만 진행
```python
# replace 메서드의 기본 형식
str.replace(old, new[, count])
# [, count] 가 무엇인지?
- optional elements 를 의미 (선택적 인자)
- 파이썬 문법이 아니라, 프로그래밍 언어를 문서상에서 잘 표현하기 위한 BNF 표기법
# 예시
'coo'.replace('o', '!')
=> 'c!!'
'wooo'.replace('o', '!', 2)
=> 'w!!o'
```.strip()
- 특정한 문자들을 지정하면 양쪽 제거(strip), 왼쪽 제거(lstrip), 오른쪽 제거(rstrip) 가능함
- 인자값을 넣지 않으면 기본적으로 공백을 제거함
- 인자값으로 문자열을 지정하면, 지정한 문자열을 제거
```python
# 형식
str.strip([chars])
# 예시
' 테스트 \n'.strip()
=> '테스트'
' 테스트 '.rstrip()
=> ' 테스트'
'www.example.com'.strip('wcom')
=> '.example.'
```.split()
- 문자열을 특정한 단위로 나눠 리스트로 반환
```python
# 기본 형식
str.split(set=None, maxsplit = -1)
# 예시
'a,b,c'.split('_')
=> ['a,b,c']
'a b c'.split()
=> ['a', 'b', 'c']
```.join()
- 반복 가능한(iterable) 컨테이너의 요소들을 seperator(구분자)로 합쳐 문자열 반환
```python
# 기본 형식
'seperator'.join(iterable)
# 예시
'!'.join('green')
=> 'g!r!e!e!n'
' '.join(['3', '5'])
=> '3 5'
```문자열 변경
- .capitalize()
- 앞글자를 대문자로, 나머지는 소문자로
- .title()
- 공백 이후의 단어 첫 문자를 대문자로
- .upper()
- 모두 대문자로
- .lower()
- 모두 소문자로
- .swapcase()
- 반대의 경우(대-소)로 변경함
- .capitalize()
문자열 검증 (True or False 반환)
.isalpha()
- 알파벳 문자 여부
- 단순 알파벳이 아는 유니코드 상의 letter (한글도 포함됨)
.isupper()
- 대문자 여부
.islower()
- 소문자 여부
.istitle()
- 타이틀 형식 여부
.isdecimal(), .isdigit(), .isnumeric()
리스트
- 특징
- 변경 가능하고(mutable)
- 순서가 있고(ordered)
- 순회 가능함(iterable)
리스트 관련 메서드
값 추가 및 삭제
.append()
- 리스트의 끝에 값을 추가함
.extend()
- 리스트에 iterable의 항목을 추가함
- append() 와는 차이가 있다
- 인자값이 iterable로서 들어가며, iterable의 요소들이 하나씩 추가됨
#기본 형식 list.extend(iterable) # 예시 cafe = ['starbucks', 'tomntoms'] cafe.extend(['hollys']) print(cafe) => ['starbucks', 'tomntoms', 'hollys'] # 단순 문자열을 넣었을 때? cafe = ['starbucks', 'tomntoms'] cafe.extend('hollys') print(cafe) => ['starbucks', 'tomntoms', 'h', 'o', 'l', 'l', 'y', 's'].insert()
- 정해진 위치 i에 값 x를 추가함
- 범위를 넘어서는 인덱스 값을 인자로 넣으면, 에러가 나는 것이 아니라 맨 끝에 추가됨
# 기본 형식 list.insert(i, x) # 예시 cafe = ['starbucks', 'tomntoms'] cafe.insert(0, 'start') print(cafe) => ['start', 'starbucks', 'tomntoms'] cafe.insert(100, 'end') print(cafe) => ['start', 'starbucks', 'tomntoms', 'end'].remove()
- 리스트에서 값이 x인 첫 번째 항목 삭제
# 기본 형식 list.remove(x) numbers = [1, 2, 3, 'hi'] numbers.remove('hi') print(numbers) => [1, 2, 3].pop()
- 정해진 위치 i에 있는 값을 삭제하고, 그 항목을 반환함
- i값을 지정하지 않으면, 마지막 항목을 삭제하고 반환함
# 형식 list.pop(i) # 예시 numbers = ['hi', 1, 2] re = numbers.pop() print(numbers) print(re) => ['hi', 1] => 2.clear()
- 리스트의 모든 항목을 삭제함
탐색 및 정렬
.index()
- 첫 번째 x값을 찾아 해당 index 값을 반환
- 찾고자 하는 x 값이 리스트 내에 없을 경우
ValueError발생
.count()
- 리스트 내에 존재하는 특정 값의 개수를 반환함
- 찾고자 하는 값이 리스트 내에 없다면 0을 반환
# 예시 numbers = [1, 2, 3, 1, 1] numbers.count(1) => 3 numbers = [1, 2, 3, 1, 1] numbers.count(9) => 0.sort()
- 원본 리스트를 정렬함
- None을 반환
- sorted 함수와 차이점 존재 (sorted의 경우 원본을 정렬하지 않고, 정렬한 결과만 반환함)
# 형식 list.sort() # 예시 numbers = [3, 2, 5, 1] result = numbers.sort() print(numbers, result) => [1, 2, 3, 5] None # sorted 함수의 예시 numbers = [3, 2, 5, 1] result = sorted(numbers) print(numbers, result) => [3, 2, 5, 1] [1, 2, 5, 3].reverse()
- 순서를 반대로 뒤집음
- 정렬하는 것은 아님
- sort()와 마찬가지로 원본을 변경하기 때문에, 반환값은 None
# 형식 list.reverse() # 예시 numbers = [3, 2, 5, 1] result = numbers.reverse() print(numbers, result) => [1, 5, 2, 3] None
리스트 복사
리스트의 복사는 같은 리스트의 주소를 참조함
해당 주소의 일부 값을 변경하는 경우 이를 참조하는 모든 변수에 영향
예시
orgin_list = [1, 2, 3] copy_list = origin_list copy_list[0] = 999 print(origin_list, copy_list) => [999, 2, 3] [999, 2, 3]
1. 얕은 복사(shallow copy)
1) 얕은 복사 - Slice 활용
Slice 연산자를 활용하여 같은 원소를 가진 리스트지만 연산된 결과를 복사함
위의 할당과는 다르게, 각 변수는 다른 주소의 리스트를 참조함
이 경우, 특정 리스트의 일부 값을 변경해도 나머지 리스트에 영향을 미치지 않음
예시
orgin_list = [1, 2, 3] copy_list = origin_list[:] copy_list[0] = 999 print(origin_list, copy_list) => [1, 2, 3] [999, 2, 3]
2) 얕은 복사 - list() 활용
얕은 복사 - list() 활용
- list()를 활용하여 같은 원소를 가진 리스트지만 연산된 결과를 복사함
- 마찬가지로 다른 주소를 참조하게 됨
예시
orgin_list = [1, 2, 3] copy_list = list(origin_list) copy_list[0] = 999 print(origin_list, copy_list) => [1, 2, 3] [999, 2, 3]
얕은복사 주의사항
- 복사하는 리스트의 원소가 주소를 참조하는 경우
- 리스트 내의 리스트는 여전히 같은 주소를 참조함
- 예시
# 얕은 복사 시,리 스트 내의 리스트 값을 변경하면? a = [1, 2, ['a', 'b']] b = a[:] b[2][0] = 0 print(a, b) => [1, 2, [0, 'b']] [1, 2, [0, 'b']] # 얕은 복사를 했음에도, 리스트 안의 리스트 내 요소는 함께 변경됨을 알 수 있음
2. 깊은 복사(deep copy)
copy 모듈을 불러와서 실행
예시
import copy a = [1, 2, ['a', 'b']] b = copy.deepcopy(a) b[2][0] = 0 print(a, b) => [1, 2, ['a', 'b']] [1, 2, [0, 'b']]
List Comprehension
표현식과 제어문을 통해 특정한 값을 가진 리스트를 생성하는 법
한 줄로 표현 가능함
예시
# 1 - 3의 세제곱 리스트 만들기 # 일반적인 방법 cubic_list = [] for number in range(1, 4): cubic_list.append(number ** 3) print(cubic_list) => [1, 8, 27] # list comprehension을 활용해 한 줄로 만들어보기 [number**3 for number in range(1, 4)] => [1, 8, 27]# 1 - 3 숫자 중 짝수만 담긴 리스트를 만들기 # 일반적인 방법 even_list = [] for number in range(1, 4): if number % 2 == 0: even_list.append(number) print(even_list) => [2] # list comprehension을 활용해 한 줄로 만들어보기 [x for x in range(1, 4) if x % 2 == 0] => [2]# 각 element를 짝지어 튜플 객체를 리스트에 담기 girls = ['kim', 'lim'] boys = ['lee', 'kwon'] # 반복문 활용 pair = [] for boy in boys: for girl in girls: pair.append((boy, girl)) => [('lee', 'kim'), ('lee', 'lim'), ('kwon', 'kim'), ('kwon', 'lim')] # list comprehension 이용 [(boy, girl) for boy in boys for girl in girls] # 간략하긴 하나, 가독성이 좋진 않음위 예시처럼, 리스트를 한 줄로 만들 수 있다는 장점이 있으나 사용하는 것이 반드시 좋은 것은 아님
가독성을 고려하면서 사용해야
# map과 list comprehension의 유사성 # 변수 numbers 를 '123' 으로 만들어라 numbers = [1, 2, 3] # list comprehension a = ''.join([str(num) for num in numbers]) # map function b = ''.join(map(str, numbers))
Built-in Function - map()
- 순회가능한 데이터 구조(iterable)의 모든 요소에 함수를 적용하고, 그 결과를 map object로 반환
- 일반적으로 map object를 리스트로 형변환 하여 결과를 확인함
# 형식
map(function, iterable)
# 예시
numbers = [1, 2, 3]
result = map(str, numbers)
print(list(result))
=> ['1', '2', '3']
- 알고리즘 문제 풀이 시 유용
# 정수 2개를 입력받을 때
n, m = map(int, input().split())
Built-in Function - filter()
- 순회가능한 데이터 구조(iterable)의 모든 요소에 함수를 적용하고, 그 결과가 True인 것들을 filter object로 반환
- map()은 함수 자체의 리턴값이 반환된다면, filter의 경우 함수의 리턴값이 True인 경우만 해당 값을 반환
- 마찬가지로 리스트로 형변환하여 결과 확인
# 형식
filter(function, iterable)
# 예시
def odd(n):
return n % 2
numbers = [1, 2, 3]
result = filter(odd, numbers)
print(list(result))
=> [1, 3]
Built-in Function - zip()
- 복수의 iterable을 모아 튜플을 원소로 하는 zip object를 반환
- 각 iterable의 원소의 개수가 맞지 않을 땐?
- 동일한 갯수까지만 짝지어 반환되고, 나머지 원소는 무시됨
# 형식
zip(*iterable)
# 예시 - 각 리스트의 원소의 개수가 다를땐?
boys = ['lee', 'kwon', 'kang']
girls = ['kim', 'lim']
pair = zip(girls, boys)
print(list(pair))
=> [('kim', 'lee'), ('lim', 'kwon')]
세트
특징
- 변경 가능하고(mutable)
- 순서가 없고(unordered)
- 순회 가능함(iterable)
세트 관련 메서드
값 추가/삭제
.add()
- 세트에 값을 추가
# 형식 set.add(elem) # 예시 fruits = ['사과', '바나나'] fruits.add('딸기').update()
- 여러 값을 추가
# 형식 set.update(*others) # 예시 fruits = ['사과', '바나나'] fruits.update(['딸기', '수박']).remove()
- 세트에서 삭제하고, 없으면 KeyError
.discard()
- 세트에서 삭제하고, 없어도 에러가 발생하지 않음
.pop()
- 임의의 원소를 제거해 반환함 (set의 경우 unordered 이기 때문)
- 세트가 비어있는 경우 keyError
딕셔너리
- 특징
- 변경 가능하고(mutable)
- 순서가 없고(unordered)
- 순회 가능함(iterable)
딕셔너리 관련 메서드
조회
.get()
- key에 대응하는 value 가져옴
- key가 딕셔너리에 없어도 KeyError가 발생하지 않음
- 인자로 넣어준 default를 돌려주며, 기본 값은 None
# 형식 .get(key[, default]) # 예시
추가 및 삭제
.pop()
- key가 딕셔너리에 있으면 제거하고 해당 값을 반환
- 그렇지 않으면 default를 반환
- default 값이 없고 key가 딕셔너리에 없으면 keyError 발생
.update()
- 값을 제공하는 key, value로 갱신 (기존 key는 덮어씀)
fruits = {'apple': '사', 'banana': '바나나'} fruits.update(apple = '사과') print(fruits) => fruits = {'apple': '사과', 'banana': '바나나'}
딕셔너리 순회
- 딕셔너리는 기본적으로 key를 순회하며, key를 통해 값을 활용
- 추가 메서드를 활용하여 순회할 수 있음
- keys() : Key로 구성된 결과
- values() : Value로 구성된 결과
- items() : (Key, Value)의 튜플로 구성된 결과
Dictionary Comprehension
리스트만큼 자주 쓰진 않음
가독성의 문제예시
# 다음의 딕셔너리에서 값이 70 이상으로 구성된 딕셔너리 만들라 dusts = {'서울': 72, '대전': 82, '구미': 29, '광주': 45} result = {} for key, value in dusts.items(): if value >= 70: result[key] = value print(result) # 위 과정을 Dictionary Comprehension 으로 {key: value for key, value in dusts.items() if value > 70}
'Python' 카테고리의 다른 글
| 객체지향 프로그래밍 (0) | 2021.08.30 |
|---|---|
| 객체 (0) | 2021.08.30 |
| 제어문 (0) | 2021.08.30 |
| 컨테이너 (0) | 2021.08.30 |
| 2차원 리스트 생성 (0) | 2021.08.01 |
댓글