리스트(List) 자료형
문자열이 문자를 묶어서 갖는 자료형이었다면, 리스트는 여러 값을 묶어서 갖는 컨테이너 자료형 중에 하나다. 대괄호 안에 콤마(,)로 값이 나열되며, 이 값들은 '요소'라고 불린다. 이 세상의 온갖 데이터(숫자, 문자, 파일, 이미지 등)가 리스트의 요소가 될 수 있고, 리스트조차 리스트의 요소가 될 수 있다. Python에서 제일 많이 사용되는 자료형이니 잘 알아두자.
컨테이너 자료형
Python은 여러 값을 묶어서 가질 수 있는 컨테이너 자료형을 제공하며, 문자열(String), 리스트(List), 튜플(Tuple), 집합(Set), 딕셔너리(Dictionary) 등이 포함된다. 여러 값을 묶기 위해 문자열을 제외하고 괄호가 필요한데, 어떤 괄호를 사용하는가에 따라 자료형이 결정된다.
요소의 변경, 추가, 삭제
- 최댓값 구할 땐? max()
- 평균은? (평균을 구하는 함수는 없다.) --> sum(리스트명) / len(리스트명)
- 다른 자료형을 리스트로 변환하려면? list() or [ ] (빈 리스트 선언)
- (문자열, 리스트의) 요소 개수를 확인하려면? len()
- 연속된 정수로 리스트를 만들려면? range(0, n+1) --> 튜플, 집합, 딕셔너리 등을 만들 때도 사용
- 리스트 요소를 반복해서 추가하려면? 리스트명 = 리스트명 * 2 ---> (ex. [0] * 20)
- 빈 리스트가 되게 하려면? 리스트명 * 0
- 특정 요소나 범위를 삭제하려면?del nums[7] --- del nums[4:]
- 전체 리스트 요소를 삭제하려면? [ ]를 대입 or clear() 메서드로 초기화(nums.clear())
- 특정 요소의 값을 변경하려면? nums[1] = 0 (인덱싱 한 다음 새로운 값 대입)
- 문자열로 리스트 만들려면? list()
# 개별 문자를 요소로 갖는 리스트
list_str = list('PYTHON')
# 확인
list_str # ['P', 'Y', 'T', 'H', 'O', 'N']
- 리스트의 맨 뒤에 요소 하나를 추가하려면? append() ---> ex. nums.append([7, [8, 9]])
- 리스트의 중간에 요소 하나를 삽입하려면? insert() ---> '이 요소를 추가해서 뒤로 밀고 싶은 아이의 인덱스를 쓰기!(a자리의 값을 지정했으니, 걔를 뒤로 밀고, 그 자리에 30을 추가하세요.'
# 리스트 만들기
nums = [10, 20, 40, 50]
# 특정 위치에 요소 추가
nums.insert(2, 30) # insert(위치, 값)
# 확인
nums # [10, 20, 30, 30, 40, 50]
# 맨 마지막에 요소를 insert 메서드로 추가
nums.insert(-1, 60) # insert(위치, 값)
# 확인
nums # [10, 20, 30, 30, 40, 60, 50]
- 리스트에 리스트를 연결하려면? #1 더하자! nums + [5, 6, 7, 8, 9]
- 리스트에 리스트를 연결하려면? #2 extend([리스트...])
# extend 메서드를 사용해서 다른 리스트 연결
nums.extend([5, 6, 7, 8, 9]) # 여러 개를 넣는 애라서 1개만 넣으면 오류. '리스트 형태로 하나'를 넣어줘야!
# 확인
nums # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 5, 6, 7, 8, 9]
append()는 실제 원본에 요소를 추가해버리는 걸까? 추가된 결과를 반환만 하는 것일까?
# 리스트 메서드가 실제 리스트를 변경해 버림 # 문자열과 다르다!
a = [0, 1, 2, 3, 4, 5]
a.append(6)
print(a) # [0, 1, 2, 3, 4, 5, 6]
반환이 아니다. 앞에서 받아주지 않아도 작동이 되는 것을 보자. 그것이 이미 반환이 아니라는 증거이다. 이것이 가능한 이유는 자기가 스스로 변환이 가능한 존재이기에 그냥 해버리는 것이다. (반대로, 문자열의 경우 스스로 자기가 변환이 불가능한 것을 알아서 반환만 하고, 변수 등으로 받아주면 그때 원본에서 변화가 일어나게 된다.)
# 메서드가 반환하는 값이 없는데 받으려고 하면 안 됨
a = [0, 1, 2, 3, 4, 5]
a = a.append(6)
print(a) # None
위를 보면, 반환하는 값이 없다(None). 처리를 그냥 해버리는 것이다. 그래서 줄 게 없는데 와서 손을 내밀면, 굉장히 당황스럽다. 그래서 None을 준다.
print(nums.append(6)) # None
# print를 안써도 상관없지만, 아무것도 안 뜬다.
# print를 쓰면 인간적으로 보여서 None이라고 알려주는 것
위는, print()한테 주는 게 없다. 반환한 게 있어야 준다. 그래서 None이 나온다.
a = 'abcdefg'
print(a.upper()) # ABCDEFG
반대로, 문자열은 print()에게 주는 반환값이 있다. 그래서 print()를 썼을 때 출력이 되는 것이다. 하지만 이 코드를 아무리 돌리더라도 문자열 메소드는 문자열 자체를 변경하지는 못한다. 헷갈리니까 꼭 외우자!
2차원 리스트(List of List)
리스트는 리스트조차 요소로 담을 수 있다. 리스트를 요소로 갖는 리스트를 2차원 리스트라고 한다.
# 2차원 리스트 만들기
score = [[80, 90, 75],
[85, 70, 99],
[90, 75, 80]]
# 확인
print(score) # [[80, 90, 75], [85, 70, 99], [90, 75, 80]]
print(len(score)) # 3
print(score[0]) # [80, 90, 75]
print(score[0][1]) # 90
# 리스트를 요소로 갖는 리스트의 인덱싱
score = [80, [90, 100, 85], 85, 90]
# 인덱싱
print(score[1]) # [90, 100, 85]
print(score[1][1]) # 100
print(score[1][-1]) # 85
# 리스트를 요소로 갖는 리스트의 슬라이싱
score = [80, [90, 100, 85], 85, 90]
# 슬라이싱
print(score[1][1:]) # [100, 85]
리스트 관련 기타 메서드
다음 메서드들은 알아두면 편리하게 쓰일 때가 많다.
문자열 관련 메서드에 의한 변경은 변수에 바로 반영되지 않지만, 리스트 관련 메서드에 의한 변경은 변수에 바로 반영되는 것이 특징이다.
- 리스트의 요소 개수를 조회하고 싶다면? a.count(요소명) ---> 리스트a에서 괄호 내 요소가 몇 개인지 확인!
- 리스트의 요소 위치를 조회하고 싶다면? a.index(요소명) --> 리스트a에서 괄호 내 요소가 첨 나타나는 위치!
- 리스트에 요소 1개나 리스트 1개를 추가하고 싶다면? a.append(85), a.append([85, 95, 90, 70, 85])
- 리스트의 요소 위치를 다 뒤집어버리고 싶다면? a.reverse()
- 리스트 요소의 순서를 오름/내림차순으로 정렬하고 싶다면? a.sort()
# 리스트 만들기
member = ['홍길동', '일지매', '박여인', '한사랑', '강우동']
# 리스트 안의 요소를 내림차순으로 정렬
member.sort(reverse=True) # 디폴트값은 reverse=False(오름차순)
# 확인
member # ['홍길동', '한사랑', '일지매', '박여인', '강우동']
- 요소를 삭제하고 싶다면? a.remove(), a.pop(), a.clear()
remove()
한번 더 실행하면 뒤의 것도 지울 수 있다. 만약 맨 뒤의 것만 삭제하고 싶다면, reverse한 다음에 맨 앞에 있는 것을 remove로 삭제하면 된다. 너무 요소가 많은데 그 값을 찾아야 하고, 인덱스값을 모를 때 이걸 사용할 수 있다.
# 리스트 만들기
member = ['홍길동', '일지매', '박여인', '한사랑', '박여인', '강우동']
# 첫 번째 '박여인' 삭제
member.remove('박여인')
pop()
지우면서 반환도 해주는 애가 pop이다. 처리도 하고, 반환도 한다. del은 지우면서 걔가 누군지..? 몰라! 이런 애고, pop은 지운 애가 과연 누굴까? 하고 궁금해하고, 반환도 한다. pop을 쓰면 우리는 지워진 값이 무엇인지 궁금할 때 활용해서 조회해볼 수 있다.
# 3번째 요소 삭제
del_member = member.pop(2)
# 확인
print(del_member) # 한사랑
print(member) # ['홍길동', '일지매', '박여인', '강우동']
# 리스트 만들기
del_member = []
member = ['홍길동', '일지매', '박여인', '한사랑', '박여인', '강우동']
# 요소 삭제
del_member.append(member.pop(0)) # member 첫 요소 제거 --> 홍길동을 del_member에 추가
del_member.append(member.pop(0)) # member 첫 요소 제거 --> 일지매를 del_member에 추가
del_member.append(member.pop(0)) # member 첫 요소 제거 --> 박여인을 del_member에 추가
# 확인
print(del_member) # 홍길동 일지매 박여인
print(member) # 한사랑 박여인 강우동
clear()
모조리 지워버리고, [ ]만 남는다.
# 모든 요소 삭제
member.clear()
# 확인
member # []
튜플(Tuple) 자료형
튜플은 리스트와 정말 비슷한 자료형이다. 대괄호[ ]가 아닌 소괄호()를 사용해서 표현한다. 튜플은 한번 만들면 요소의 값을 바꿀 수 없다는 것이 리스트와 다르다. (다시 선언하든가 해야 한다...) 그 외에는 리스트와 같은 특성을 가지므로 이해하기 쉬울 것이다. 인덱싱과 슬라이싱, print(), 연결(+)과 반복(*)은 리스트와 같으나, 제거와 추가와 관련된 메서드는 확인 불가능하다.
- b[0] = 10 ---> X! 요소 변경 불가
튜플은 언제 사용되는가?
나중에 데이터 분석하거나 머신러닝, 딥러닝을 할 때 데이터에 대한 정보를 확인한다. csv를 확인할 때, shape로 확인하는데, 함수의 결과가 튜플로 떨어지게 된다. 왜 그러냐 하면, 이건 shape가 반환한 것이니까 변경되지 않을 것임을 알려주기 위해 튜플로 떨어지게 하는 것이다. 우리가 그 값을 받을 때 튜플이어서 편리한 점이 있다. 잠깐 나타났다 사라지게 되는 역할이다. 자주 만나는데, 자주 만나지는 않는 게 튜플이다.
튜플 활용
괄호를 생략할 수 있는 튜플의 특징을 이용하면 편리한 부분이 있다. 믿을 수 있는 것이다. 보안성이라고 하면 초기화할 수 없어야 하고 변수를 날릴 수도 없어야 한다. 보안은 좀 너무 큰 해석이긴 하지만, 어떤 튜플의 값을 받았는데, 변경된 값이 아니라는 믿음이라고 해석해보면 좋겠다.
1. 소괄호의 생략을 통해 환상적인 구문 만들기
c = a, b는 튜플로 간주할 수 있다. 실제로 소괄호 없이도 파이썬은 자동으로 튜플로 처리한다.
# 괄호 없이 튜플 만들기
a = 10 # (10)
b = 20 # (20)
c = a, b # (a, b)
# 확인
c # (10, 20)
2. 여러 변수에 동시에 값 대입 가능
파이썬에서는 튜플과 관련된 특성 덕분에 여러 변수를 동시에 대입하는 문법을 간단하게 사용할 수 있다.
# 여러 변수에 동시에 값 대입
a, b, c = 10, 20, 30
print('a =', a) # a = 10
print('b =', b) # b = 20
print('c =', c) # c = 30
# 여러 변수에 동시에 값 대입(튜플 포함)
a, b, c = 10, 20, (1, 2, 3)
print('a =', a) # a = 10
print('b =', b) # b = 20
print('c =', c) # c = (1, 2, 3)
3. 두 변수의 값을 교환 가능
중간 값을 경유하지 않아도(c=a, a=b, b=c) 이렇게 튜플을 활용할 수 있다.
# 변수 값 서로 변경
a, b = 10, 20
print('a =', a, 'b =', b) # a = 10 b = 20
a, b = (b, a)
print('a =', a, 'b =', b) # a = 20 b = 10
4. 함수 리턴값을 두 변수에 대입 가능
divmod(a, b)는 튜플이다. (2, 5)가 된다. 함수는 튜플 형태의 값을 반환해준다.
# 튜플 사용
a, b = 45, 20
x, y = divmod(a, b) # divmob : a로 b를 나눌 때 몫과 나머지를 반환하는 함수
print(x, y) # 2 5
다양한 튜플 만들기
1. 빈 튜플 만들기
비어있는 튜플을 만들 일은 거의 없다. 집어넣을 수가 없기 때문에 쓸 일이 거의 없다. 대신, 튜플을 완전히 제거하는 목적으로 값이 없는 튜플로 바꿀 때는 의미가 있다.
# 빈 튜플 만들기 #1
score = () # 소괄호를 비어있게 작성해도 좋다
# 확인
score # ()
# 빈 튜플 만들기 #2
score = tuple() # 자료형과 똑같은 이름의 함수를 써도 된다.
# 확인
score # ()
2. 요소가 하나인 튜플 만들기
튜플은 여러 개의 값을 가질 것이기 때문에 그 의지를 표현해줘야 한다. 그래야 튜플이 된다. 다른 데에서 갑자기 수 뒤에서 ,가 있는 경우가 있는데 그건 그냥 붙인 게 아니라, 튜플임을 알려주는 것이다.
# 요소가 하나인 튜플 만들기 #1
score = (90,)
# 확인
print(score) # (90,)
print(type(score)) # <class 'tuple'>
print(len(score)) # 1
# 요소가 하나인 튜플 만들기 #2
score = 90,
# 확인
print(score) # (90,)
print(type(score)) # <class 'tuple'>
print(len(score)) # 1
3. 다양한 형태의 튜플
튜플도 리스트처럼 모든 것을 포함시킬 수 있다. 튜플도 품을 수 있고, 리스트도 품을 수 있다. 그러나 변경할 수는 없다.
한편 소괄호를 생략한 형태도, 씌운 형태도 똑같은 튜플이다.
# 여러 형태의 튜플 만들기
score1 = (90, 85, 70)
score2 = 90, 85, 70
score3 = (90, 85, 70, ('A', 'B', 'D', 'F'))
# 확인
print(score1) # (90, 85, 70)
print(score2) # (90, 85, 70)
print(score3) # (90, 85, 70, ('A', 'B', 'D', 'F'))
4. 문자열로 튜플 만들기
# 문자열로 튜플 만들기 #1
chars = ('PYTHON',)
# 확인
print(chars) # ('P', 'Y', 'T', 'H', 'O', 'N')
# 문자열로 튜플 만들기 #2
chars = tuple('PYTHON')
# 확인
print(chars) # ('P', 'Y', 'T', 'H', 'O', 'N')
변경할 수 없다! 그런데, 튜플이 리스트를 포함하고 있다면 리스트 요소를 변경할 수 있나?
튜플은 이 세상의 모든 것을 다 포함할 수 있기에 리스트도 포함할 수 있다. 여기에서 리스트 요소의 맨 앞 요소를 변경할 수 있을까?
# 튜플 선언
t = (1, 2, 3, 4, 5, [1, 2, 3, 4, 5])
print(t) # (1, 2, 3, 4, 5, [1, 2, 3, 4, 5])
print(t[-1]) # [1, 2, 3, 4, 5]
# 리스트 변경
t[-1][0] = 10 # 리스트를 바꾼 것이지, 튜플을 바꾼 것이 아니다.
print(t) # (1, 2, 3, 4, 5, [10, 2, 3, 4, 5])
리스트가 변경 가능해서 리스트의 값을 바꾸었다. 그러나 튜플의 값 자체를 바꾼 건 아니다. 리스트는 튜플의 요소라 바꿀 수 없지만, 그 리스트 안의 값은 바꿀 수 있다. 마치 남편이 아내와 딸은 바꿀 수 없지만, 아내나 딸이 가지고 있는 스마트폰은 바꿔줄 수 있는 것과 같다.
range() 함수를 활용해 만들기
# range() 함수를 사용해 튜플 만들기
nums = tuple(range(0, 11))
# 확인
print(nums)
# range() 함수를 사용해 리스트 만들기
nums = list(range(0, 11))
# 확인
print(nums)
range() 함수는 그 값이 그냥 범위이다. 그게 그냥 객체이다. range() 함수가 리스트나 튜플 자체를 반환하는 게 아니라, 범위 객체를 반환하기 때문이다. range(0, 11)은 0에서 10까지의 숫자를 담고 있는 range 객체를 반환한다. 이 객체는 반복 가능하지만, 리스트나 튜플로 직접 변환되지 않으면 범위 객체 자체가 리스트나 튜플로 들어가게 된다. 원하는 것은 range(0, 11)의 숫자들을 리스트에 담는 것이므로, 이를 해결하기 위해서는 list() 함수를 사용해 범위 객체를 튜플이나 리스트로 변환해야 한다.
- nums = range(0, 11)의 결과 --> 튜플이 되는 게 아니라 범위이다.
- nums = (range(0, 11),) --> range 범위 자체를 품어버리게 된다. 소괄호 생략 가능하므로 range(0, 11)이 되어버린다.
- nums = [range(0, 11)] --> 리스트가 되지 않는다. 범위는 값이 아니기 때문에, 리스트가 아닌 range 객체가 리스트에 들어가서 기대한 대로 출력되지 않는다.
튜플과 딕셔너리 키
튜플은 값이 변하지 않는다는 속성 때문에 딕셔너리의 키로 사용될 수 있다. 딕셔너리 키는 바뀔 수 없기 때문이다. 한편, 리스트는 딕셔너리 키로 사용될 수 없다.
my_dic = {(1, 2, 3): '일이삼',
(4, 5, 6): '사오육'}
print(my_dic[(1, 2, 3)])
집합(Set) 자료형
집합 연산(교집합, 합집합, 차집합, 대칭 차집합)을 위한 자료형으로, 중복을 허용하지 않으며, 원소의 순서가 의미가 없어 인덱싱과 슬라이싱으로 값을 얻을 수 없다. { }로 표현되고, 집합 안에는 문자열, 정수형, bool 등 여러 자료형을 가질 수 있다. 그러나 리스트와 튜플은 집합에 담을 수 없다.
입력을 3, 4 순으로 했는데 왜 3이 4보다 뒤로 갔나요?
의문을 가질 필요가 없다. 오름차순 내림차순이 자동으로 되는 건가? 안 된다. 순서가 의미가 없다. 그냥 여기 안에 이게 들어있네. 하는 것 말고는 할 수 있는 게 없다.
아래에서 왜 True는 출력이 안 되고, False는 출력이 안 되는가?
어떤 값을 bool로 가지고 할 수 있다. 10을 bool로 바꾸면 True이다. etc 값은 다 True이다. 그래서 같은 값이라 중복이기 때문에 출력이 안 된 것이다. False가 되려면 0이나 공백이어야 한다. 그게 안에 있었으면 그것도 출력이 안 됐을 것이다.
# 여러 자료형을 갖는 집합
etc = {'한사랑', 1, 2, 3, '한국', False, True}
# 확인
etc # {1, 2, 3, False, '한국', '한사랑'}
집합으로 자료형 변환
set() 함수를 사용해 다른 자료형을 집합으로 변환한다. 이때, 같은 요소를 갖지 않는 집합의 특징에 따라 중복된 요소는 제거된다.
문자열, range(), 리스트, 튜플
set() 함수로 개별 문자를 요소로 갖는 집합을 만들 수 있다. 같은 요소를 갖지 않는 집합의 특징에 따라 중복된 문자는 제거된다.
- set('잘지내지요') --> {'내', '요', '잘', '지'}
- set(range(0, 10)) --> {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
집합 정보 확인
- len() 함수로 집합에 포함된 원소 개수를 확인한다. --> print(len(member1)) --> 4
- in 연자로 집합에 요소가 속해 있는지 확인한다. --> print('홍길동' in member1) --> True/False
(in은 수가 너무 많을 때, 거기 안에 있는지 확인하려고 본다.)
집합 활용: list(), tuple(), set() 함수 활용
리스트, 튜플 중복 요소 제거(.sort()를 통해 오름차순으로 정렬도 가능)
# 리스트 만들기
nums = [12, 45, 23, 21, 36, 28, 12, 36, 35, 28, 45, 63, 12, 21]
# 리스트 --> 집합 변환 -> 리스트 변환
nums = list(set(nums))
# 오름차순 정렬
nums.sort() # 이러면 오름차순이 된다.
#확인
nums
집합 연산
일반적인 집합 연산 개념이 집합 자료형에 그대로 사용이 가능하다. (합집합에서 교집합을 뺀 것을 대칭 차집합이라고 한다.)
1. 합집합: | or union()
- member_set1 | member_set2 # 세로막대 = '합집합'
- member_set1.union(member_set2) = member_set2.union(member_set1) # 동일결과
2. 교집합: & or intersection()
- member_set1 & member_set2
- member_set1.intersection(member_set2) = member_set1.intersection(member_set2)
# 동일결과
3. 차집합: - or difference()
- member_set1 - member_set2
- member_set1.difference(member_set2)
4. 대칭 차집합: ^ or symmetric_difference()
- member_set1 ^ member_set2
- member_set1.symmetric_difference(member_set2)
집합 활용: 집합 연산을 통한 사용
1. 리스트 중복 확인
교집합을 활용해 두 리스트 사이의 중복된 요소 확인
# 리스트 만들기
nums1 = [12, 23, 32, 36, 41, 48]
nums2 = [12, 19, 24, 32, 36, 47]
# 집합 변환 후 교집합 구하기
nums = list(set(nums1) & set(nums2))
#확인
nums # [32, 36, 12]
2. 리스트 중복 없이 합치기
합집합 기능을 활용해 두 리스트의 중복된 요소를 제거하면서 합칠 수 있다.
# 리스트 만들기
nums1 = [12, 23, 32, 36, 41, 48]
nums2 = [12, 19, 24, 32, 36, 47]
# 집합 변환 후 합집합 구하기
nums = list(set(nums1) | set(nums2))
# 집합 --> 리스트 변환
#확인
nums # [32, 36, 41, 12, 47, 48, 19, 23, 24]
.sort()를 사용할 때 주의할 점
아래의 결과는 None이 된다. sort()를 하면 결과를 정렬했을 것이다. 그런데 정렬하고 끝나는 것이고, 반환해주는 것이 없다. 그래서 받는 게 없다. 그래서 손 내밀었다가 부끄러워서 None이 되는 것이다.
- num.sort() ---> (O)
- num = num.sort() ---> (X)
집합 관련 메서드
- 요소 하나 추가: add() ---> ex. member.add('강우동') / (리스트는 append()였다. 그러나 맨 뒤가 아니라 그냥 넣은 것)
- 여러 요소 추가: update() ---> ex. member.update(['한국인', '나도야']) / (리스트는 extend()였다. 그러나 뒤에 넣어서 확장이 아닌, 이것저것 넣어서 변한 것)
- 무작위 한 요소 삭제: pop() ---> ex. del_member = member.pop() / (리스트와 달리 인덱스가 없으니 괄호에 뭘 넣지 X)
- 요소 삭제(없으면 오류): remove() ---> ex. member.remove('일지매') / 오류 메시지 출력
- 요소 삭제(없으면 무시): discard() ---> ex. member.discard('홍길동') / 오류 메시지 무시
- 변경하고 싶다면? remove()로 지우고 add()로 추가!
- 모든 원소 삭제(1): clear() ---> ex. member.clear() ---> 결과: set()
모든 원소 삭제할 때 { } 써주면 안 되나?
이 중괄호는 딕셔너리도 쓰고, 집합도 쓴다. { }로 재선언해주면 중괄호는 딕셔너리라고 인식된다. 그래서 집합은 이런 식으로 초기화하면 안 된다. .clear()로 초기화해줘야 한다.
딕셔너리(Dictionary) 자료형
사전은 단어가 중요하다. 단어가 key가 되어서 이 key를 찾아가서 그 설명을 보는 것이다. 단어가 몇 번째 있느냐는 별로 의미가 없다. 이게 dict에서도 동일하다. 우리는 앞으로 key로 해서 value로 찾을 것이다.
딕셔너리는 집합과 마찬가지로 중괄호{ }를 사용해서 선언하며, 순서의 의미가 없다. 또한 리스트나 튜플을 Value로 가질 수 있다.
딕셔너리 요소 순서
파이썬 3.6부터 딕셔너리가 내부적으로 삽입 순서를 유지하기 시작했다. 따라서 삽입된 요소 순서를 유지하게 된다.
딕셔너리의 특징
1. key로 value를 찾는다! 사전처럼
# 영어:한글
word = {'love': '사랑', 'happy': '행복', 'dream': '꿈'}
# key로 value를 찾는다. 마치 사전처럼!
word['love'] # '사랑'
# value로 key를 찾을 수는 없다.
word['사랑'] # (오류)
2. key는 중복이 되지 않는다.
key는 중복되지 않고, key에 대해서 마지막 주었던 값만 남는다. 그게 바로 dict!
# 영어:한글
word = {'love': '사랑', 'happy': '행복', 'dream': '꿈', 'love': '애정'}
# 확인
word # {'love': '애정', 'happy': '행복', 'dream': '꿈'}
3. 다양한 정보를 갖는다.
리스트나 튜플을 Value로 가질 수 있으며, 이 때문에 해당 요소에 대한 인덱싱이 가능하다.
# Value가 리스트인 딕셔너리
member2 = {'이름': '홍길동',
'취미': ['독서', '여행', '걷기']}
# 걷기를 가져오려면? # 리스트니까 인덱싱을 할 수 있다.
member2['취미'][-1] # '걷기'
4. 헷갈리지 말자! 숫자가 key인 경우
숫자도 key가 될 수 있기에, 익숙하지 않은 형태에 헷갈리지 말자! 인덱싱이 가능한 게 아니라, 우연히 모양이 겹친 것이다.
- nums[1]에서 1은 index가 아니라, key라는 점에 주의하자.
# 숫자가 Key인 리스트
nums = {1: 10, 2: 20, 3: 30}
# 10을 조회하고 싶으면?
nums[1] # 10
5. 리스트는 key가 될 수 없다.
당연히도, key는 변경되면 안 된다. (기존의 key를 날리고 뒤에 새로 추가해야만 한다..) 변경되면 안되기에 리스트가 key가 될 수는 없다. 튜플은 변경 불가능한 자료형이기에 key가 될 수 있지만, 리스트는 변경 가능한 자료형이기에 리스트는 딕셔너리의 key가 될 수 없다.
# Key가 리스트인 딕셔너리(?)
member = {['이름', '나이']: ['홍길동', 20]} # ERR: unhashable type: 'list'
6. value값에 튜플...? 권고하지 않는다!
바꿀 것이 아니라면, 튜플로 넣어도 된다. 그런데 보통 딕셔너리는 바꿔야 할 경우들이 많다. 그래서 대개 리스트로 하는 것을 권고한다.
딕셔너리 변경, 추가와 삭제
1. 딕셔너리 추가
인덱스 대신 key로 찾아 변경한다는 것 외에는 리스트와 같다. a가 딕셔너리에 없었으면 오히려 추가가 되어버린다. key가 있으면 그 값을 바꾸고, 없으면 그 key와 value가 추가가 된다는 것을 기억하자.
# 딕셔너리 만들기
member = {'이름': '홍길동',
'나이': 20}
# 딕셔너리 요소 값 변경(나이 = 30)
member['나이'] = 30
# 확인
member # {'이름': '홍길동', '나이': 30}
2. 딕셔너리 삭제
- del 문: key를 지정해 해당 요소를 삭제할 수 있다.
- pop() 메서드: key를 지정해서 요소를 삭제하며, 삭제된 요소의 value를 반환받는다.
- popitem() 메서드: key 지정 없이 마지막 요소부터 삭제 가능하며, 삭제된 요소의 key와 value를 튜플 형태로 반환받음
- = {} : 모든 요소 삭제
# 딕셔너리 만들기
member = {'이름': '홍길동',
'나이': 20,
'지역':'서울',
'성별': 'M',
'등급': 'Gold'}
# 지정한 요소 삭제 #1
del member['나이']
# 확인
member # {'이름': '홍길동', '지역': '서울', '성별': 'M', '등급': 'Gold'}
# 지정한 요소 삭제 #2
del_member = member.pop('지역')
# 확인
print(del_member) # 서울 # dict에서의 pop은 제거된 value(값)을 던져준다. 반환한다.
print(member) # {'이름': '홍길동', '나이': 20, '성별': 'M', '등급': 'Gold'}
# 임의 요소 삭제 #3
del_member = member.popitem()
# 확인
print(del_member) # ('등급', 'Gold')
print(member) # {'이름': '홍길동', '나이': 20, '성별': 'M'}
딕셔너리 관련 메서드
- key: value의 쌍 형태를 갖는 요소를 갖고 있다면, 딕셔너리로 어떻게 변환? dict()
- 해당 key가 있는지 확인? in 연산자 ---> ex. print('이름' in member), print('여행' in member['취미']) --> 결과: True/False
- key 정보를 확인하고 싶다면? keys() ---> ex. member.keys()
- value 정보를 확인하고 싶다면? values() ---> ex. member.values()
- key와 value 정보를 같이 확인하고 싶다면? items() ---> ex. member.items() / (튜플 형태로 준다.)
- 모든 요소 삭제? clear() ---> ex. member.clear()
- 오류 메시지 없이 key로 value찾고 싶을 때? get() ---> ex. member.get('이메일', '없음') / (없으면 '없음'을 반환)
'데이터 분석 > 파이썬 기초' 카테고리의 다른 글
제어문(Control Statements)을 알아보자. (1) | 2024.09.16 |
---|---|
변하는 것과 변하지 않는 것 (0) | 2024.09.15 |
문자열 자료형에 대해 이해해보자. (1) | 2024.09.11 |
값이 같다? 존재가 같다? (0) | 2024.09.10 |
연산자와 기본 자료형에 대해 알아보자. (0) | 2024.09.09 |