pass
05wk-2: 파이썬의 자료형 (2)
1. 강의영상
2. Imports
3. tuple
A. 리스트 vs 튜플
-
공통점: (1) 컨테이너형타입이라는 점, 그리고 (2) 연산 및 인덱싱을 하는 방법은 리스트와 같음 - 차이점1: [] 대신에 ()를 사용한다. - 차이점2: 불변형이다. (원소의 값을 바꿀 수 없음) - 차이점3: 하나의 원소를 선언할 때는 (1,)와 같이 해야 한다. - 차이점4: 의미가 명확할때는 튜플의 ()를 생략가능하다.
-
컨테이너형이라는 것이 무슨의미?
=(4,6,'pencil', 3.2+4.6j, [3,4]) a
type(a[2])
str
type(a[3])
complex
-
연산의 유사성
1,2) + (3,4,5) (
(1, 2, 3, 4, 5)
1,2) * 2 (
(1, 2, 1, 2)
-
인덱싱의 유사성
= (11,21,31)
tpl 1:] tpl[
(21, 31)
-
차이점2: 불변형이라는 것은 무슨의미?
2] = 'Pencil' a[
TypeError: 'tuple' object does not support item assignment
참고로 a를 튜플이 아니라 리스트로 선언하면 값이 잘 바뀐다.
=[4,6,'pencil', 3.2+4.6j, [3,4]] a
2] a[
'pencil'
2]='Pencil' a[
a
[4, 6, 'Pencil', (3.2+4.6j), [3, 4]]
-
차이점3: 하나의 원소로 이루어진 튜플을 만들때는 쉼표를 붙여야 함.
1]+[2,3,4] [
[1, 2, 3, 4]
1,)+(2,3,4) (
(1, 2, 3, 4)
-
차이점4: 의미가 명확할때 튜플의 괄호는 생략가능하다. (이게 중요합니다)
=1,2
a a
(1, 2)
의미가 명확할때 생략해야함
1,2 + 3,4,5
(1, 5, 4, 5)
1,2) + (3,4,5) (
(1, 2, 3, 4, 5)
B. 선언
-
소괄호를 이용
=(1,2,3)
a a
(1, 2, 3)
type(a)
tuple
-
생략가능하다는 점이 포인트
=1,2,3
a a
(1, 2, 3)
type(a)
tuple
-
원소가 하나인 튜플을 만들고 싶다면?
=(1,)
a a
(1,)
C. 연산
-
리스트와 동일
1,2)+(3,4,5) (
(1, 2, 3, 4, 5)
1,2)*2 (
(1, 2, 1, 2)
D. 인덱싱
-
리스트와 동일
=(1,2,3,-4,-5)
a a
(1, 2, 3, -4, -5)
-1] a[
-5
-3:] a[
(3, -4, -5)
E. 슬기로운 튜플사용 (\(\star\))
# 예제
– 여러변수를 동시에 출력하고 싶을 경우 (다중출력?)
변수를 아래와 같이 선언하였다고 하자.
=1
a=2
b=3 c
선언된 값을 확인하려면?
a
1
b
2
c
3
튜플을 이용하면?
# 괄호하나 생략하는것이 이렇게 편하다.. a,b,c
(1, 2, 3)
#
# 예제2
– 다중할당1 (여러개의 변수를 동시에 선언하고 싶을 경우)
아래와 같이 =
를 5번 쓰면 5개의 변수를 선언할 수 있다.
= 'Tom'
name = 20
age = 'M'
sex = 180
height = 70 weight
튜플을 이용하면 좀더 간단히 하나의 =
로도 아래와 같이 선언할 수 있다.
= 'Tom', 20, 'M', 180, 70 # 다중할당 name, age, sex, height, weight
#
# 예제2
– 다중할당2, 위도와 경도
= (37,127) # 서울
coor coor
(37, 127)
long = coor # 다중할당 lat,
lat
37
long
127
#
# 잠깐만
– 다중할당은 꼭 튜플에서만 가능한가?
그건 아니다…
= [1,2,3]
[x,y,z] # 다중출력 x,y,z
(1, 2, 3)
= 'hi'
[x,y] x,y
('h', 'i')
튜플과 같이 사용하면 가독성이 극대화 (그래서 다중할당은 거의 튜플과 세트로 사용함)
= 1,2,3
x,y,z # 다중출력 x,y,z
(1, 2, 3)
= 'hi'
x,y x,y
('h', 'i')
#
# 예제
– 임시변수 사용없이 두 변수의 값을 교환
=10
a=20 b
a,b
(10, 20)
= b,a a,b
a,b
(20, 10)
#
# 예제
– for문과 튜플
= [['guebin', 202112345, 'M'],
lst 'iu',202254321, 'F'],
['hodong', 202011223, 'M']]
[ lst
[['guebin', 202112345, 'M'],
['iu', 202254321, 'F'],
['hodong', 202011223, 'M']]
0] lst[
['guebin', 202112345, 'M']
for name,studentid,sex in lst:
print(name,sex)
guebin M
iu F
hodong M
#
# 예제
– for문과 튜플, dummy variable _
for name,studentid,sex in lst:
print(studentid)
202112345
202254321
202011223
for _,studentid,_ in lst:
print(studentid)
202112345
202254321
202011223
for _,_,sex in lst:
print(sex)
M
F
M
for name,_,sex in lst:
print(name,sex)
guebin M
iu F
hodong M
for name,_,_ in lst:
print(name)
guebin
iu
hodong
#
# 예제
– 튜플과 언패킹연산자 *
아래와 같이 관심없는것 모두를 other라는 이름으로 받을 수 있음
for name,*other in lst:
print(name,other)
guebin [202112345, 'M']
iu [202254321, 'F']
hodong [202011223, 'M']
*
의 동작을 더 세심히 살펴보자.
*tail = range(1,11)
head, body, head, body, tail
(1, 2, [3, 4, 5, 6, 7, 8, 9, 10])
*body, tail1,tail2,tail3 = range(1,11)
head1,head2, head1,head2, body, tail1,tail2,tail3
(1, 2, [3, 4, 5, 6, 7], 8, 9, 10)
*head, body, tail = range(1,11)
head, body, tail
([1, 2, 3, 4, 5, 6, 7, 8], 9, 10)
(관찰)
그러고 보니까..
*head, body, tail] = [1,2,3,4,5,6,7,8,9,10]
[= [[1,2,3,4,5,6,7,8],9,10] [head, body, tail]
이렇다는 거잖아?
*
를 붙이면 1차원 자료구조가 풀린다..?
1,2,[1,2,3]] [
[1, 2, [1, 2, 3]]
1,2,*[1,2,3]] [
[1, 2, 1, 2, 3]
-
단독사용은 불가능
*[1,2,3]
SyntaxError: can't use starred expression here (386627056.py, line 1)
F. 튜플을 왜 쓸까? – 제 생각..
-
질문: 리스트를 쓰지 않고 왜 튜플을 써야하나?
-
답변1: (책의 설명)
- 초보적인 설명: 실수방지
- 더 정확한 설명: 빠르다, 여러사람과 작업하기 유리하다, 깊은복사/얕은복사시 원하지 않는 오류 (side effect 이라고 함) 방지
-
답변2: 괄호를 생략할 수 있기 때문에, 리스트 말고 튜플을 쓰면 편함.
- 소괄호의 생략 + 언패킹 \(\Rightarrow\) 엄청난 가독성.
- 컴공과 사람들 의견: 튜플 + 언패킹 \(\Rightarrow\) 엄청난 가독성 \(\Rightarrow\) 충격 \(\Rightarrow\) “파이썬 편하더라고요..”
-
근본적인 의문: 파이썬을 처음 만들때 리스트에 괄호를 생략하는 기능을 추가했으면 편했잖아?
-
저의 설명: 리스트=신라면
, 튜플=라면사리
같은 느낌으로 이해하면 된다. 불변형(튜플)은 기능제한이 있는데, 가변형(리스트)는 기능이 풍부하다. 대신에, 가변형은 느리고 무겁다.
- 기능적으로만 보면, 신라면이 있으면 스프를 버리고 라면사리를 얻을 수 있음, 그래서 라면사리는 필요없음.
- 그런데 신라면에서 스프를 버려서 라면사리를 항상 얻는다면, 비효율적임.
- 우리가 원하는게 (1) 원소를 벡터형태로 모은뒤 (2) 벡터자체를 출력해보고 (3) 각 원소를
sort
하고 (4) 원소를 추가append
하고 (5) 원소를 삭제remove
하는 것 일수도 있음. 그렇지만 진짜 단순하게 (1),(2) 만 원할수도있음. - 단순히 (1)-(2)의 목적으로 리스트를 사용하는건 비효율적이니까 불변형인 튜플을 만듦. (1)-(2)를 사용함에 있어서 편리성을 극대화 하기위해 괄호도 생략하게 해줌.
def mycal(a,b):
return a+b, a-b, a*b, a/b # 여러개의 값을 리턴하는듯 보임 -> 사실은 길이가 4인 튜플 1개를 리턴
1,2) mycal(
(3, -1, 2, 0.5)
= mycal(1,2) _,_,mul,_
mul
2
G. 연습문제들
# 문제
. 길이가 1인 튜플을 만들어 자신의 학번을 저장하라. 길이가 1인 튜플을 만들어 자신의 영문이름을 저장하라. 두 튜플을 + 연산자로 합쳐아래와 같은 출력결과를 얻어라. 최종 결과는 예를들면 아래와 같아야 한다.
'2021-43052', 'GuebinChoi') (
('2021-43052', 'GuebinChoi')
(풀이)
= ('2021-43052',)
sid = ('GuebinChoi',) name
+name sid
('2021-43052', 'GuebinChoi')
파이썬프로그래밍 수강생
. 아래는 파이썬프로그래밍 수강생들의 학번, 이름, 출석점수, 과제점수, 중간고사점수, 기말고사점수를 저장한 중첩리스트이다.
= [['2021-43052', 'GuebinChoi', 5, 10, 20, 25],
lst '2019-12342', 'Heung-min Son', 10, 15, 30, 15],
['2018-32234', 'hynn', 7, 20, 30, 15],
['2022-42323', 'Minji', 8, 20, 20, 35],
['2023-55342', 'Hanni', 7, 20, 30, 35],
['2022-46624', 'Danielle', 3, 15, 30, 40],
['2022-11239', 'Haerin', 10, 20, 30, 40],
['2022-32114', 'Hyein', 10, 20, 20, 35]]
[ lst
[['2021-43052', 'GuebinChoi', 5, 10, 20, 25],
['2019-12342', 'Heung-min Son', 10, 15, 30, 15],
['2018-32234', 'hynn', 7, 20, 30, 15],
['2022-42323', 'Minji', 8, 20, 20, 35],
['2023-55342', 'Hanni', 7, 20, 30, 35],
['2022-46624', 'Danielle', 3, 15, 30, 40],
['2022-11239', 'Haerin', 10, 20, 30, 40],
['2022-32114', 'Hyein', 10, 20, 20, 35]]
# 문제
. 파이썬프로그래밍 수강생의 수는 모두 몇명인가?
(풀이)
len(lst)
8
#
. 전북대학교 지침에 따라 출석점수가 7보다 작은 학생은 (즉 출석점수 < 7
일 경우) F학점을 부여하게 되어있다. 이 기준에 따르면 F를 받는 학생은 모두 몇명인가?
(풀이)
sum([att<7 for _,_,att,*other in lst])
2
# 문제
. 파이썬프로그래밍 수업의 경우 출석+레포트 < 21
일 경우 F학점을 부여한다고 한다. 이 기준에 따르면 F를 받는 학생은 모두 몇명인가?
(풀이)
sum([att+rep<21 for _,_,att,rep,*other in lst])
2
# 문제
. 리스트의 정렬순서를 [학번, 이름, …, 기말고사점수] 가 아니라 [이름, 학번, … , 기말고사점수] 와 같이 되도록 변경하는 코드를 작성하라.
(출력예시)
'GuebinChoi', '2021-43052', 5, 10, 20, 25],
[['Heung-min Son', '2019-12342', 10, 15, 30, 15],
['hynn', '2018-32234', 7, 20, 30, 15],
['Minji', '2022-42323', 8, 20, 20, 35],
['Hanni', '2023-55342', 7, 20, 30, 35],
['Danielle', '2022-46624', 3, 15, 30, 40],
['Haerin', '2022-11239', 10, 20, 30, 40],
['Hyein', '2022-32114', 10, 20, 20, 35]] [
[['GuebinChoi', '2021-43052', 5, 10, 20, 25],
['Heung-min Son', '2019-12342', 10, 15, 30, 15],
['hynn', '2018-32234', 7, 20, 30, 15],
['Minji', '2022-42323', 8, 20, 20, 35],
['Hanni', '2023-55342', 7, 20, 30, 35],
['Danielle', '2022-46624', 3, 15, 30, 40],
['Haerin', '2022-11239', 10, 20, 30, 40],
['Hyein', '2022-32114', 10, 20, 20, 35]]
(풀이)
*other] for sid,name,*other in lst] [[name,sid,
[['GuebinChoi', '2021-43052', 5, 10, 20, 25],
['Heung-min Son', '2019-12342', 10, 15, 30, 15],
['hynn', '2018-32234', 7, 20, 30, 15],
['Minji', '2022-42323', 8, 20, 20, 35],
['Hanni', '2023-55342', 7, 20, 30, 35],
['Danielle', '2022-46624', 3, 15, 30, 40],
['Haerin', '2022-11239', 10, 20, 30, 40],
['Hyein', '2022-32114', 10, 20, 20, 35]]
4. 잡기술 (하지만 유용해)
A. 인덱싱고급 (스트라이딩)
-
스트라이딩 [start:end:step]
= list('abcdefghijk')
lst lst
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k']
len(lst)
11
0:9:2] lst[
['a', 'c', 'e', 'g', 'i']
-
생략
0:9]
lst[#lst[0:9:]
#lst[0:9:1]
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']
1::3] lst[
['b', 'e', 'h', 'k']
8:3] lst[:
['a', 'd', 'g']
# 예제1
: 짝수/홀수 원소 추출
아래와 같은 문자열이 있다고 하자.
= list('abcdefghijk')
lst lst
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k']
index = 0,2,4, ...
에 해당하는 원소를 출력하라.
2] lst[::
['a', 'c', 'e', 'g', 'i', 'k']
index = 1,4,7 ...
에 해당하는 원소를 출력하라.
1::3] lst[
['b', 'e', 'h', 'k']
#
# 예제2
– 세로로..
(예제2를 위한 예비학습) 문자열에서 \n
을 출력하면 출력시 줄바꿈이 일어난다.
print('1행\n2행\n3행')
1행
2행
3행
예비학습 끝
아래와 같은 문자열이 있다고 하자.
= '너같이사랑스럽고\n또예쁘고도멋지고\n속훤히보이는너알\n았어그동안고마웠\n지정말정말사랑해'
txt print(txt)
너같이사랑스럽고
또예쁘고도멋지고
속훤히보이는너알
았어그동안고마웠
지정말정말사랑해
위 문자열을 세로로 읽는 코드를 작성하라. (9칸씩 점프하면서 읽으면 된다)
(풀이)
9] txt[::
'너또속았지'
#
-
step = -1 이면?
lst
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k']
-1] lst[::
['k', 'j', 'i', 'h', 'g', 'f', 'e', 'd', 'c', 'b', 'a']
-
스트라이딩으로 step = -1
옵션 주기 vs 리스트의 .reverse()
메소드 이용하기
관찰1: reverse 메소드는 리스트 자체를 변화시킴
= list('abcdefgh')
lst lst
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
lst.reverse() lst
['h', 'g', 'f', 'e', 'd', 'c', 'b', 'a']
관찰2: [::-1]는 리스트는 변화시키지 않음
= list('abcdefgh')
lst lst
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
-1] lst[::
['h', 'g', 'f', 'e', 'd', 'c', 'b', 'a']
lst
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
-
-step 은 쓰기 까다롭다.
(예제) 처음과 끝을 생략하지 않고 아래와 동일한 효과를 주는 코드를 만들어 보자.
(풀이)
결국 lst[?:?:-1]의 꼴에서 적당히 ?의 값을 채우면 된다. –> 어려워
lst
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
-1] lst[::
['h', 'g', 'f', 'e', 'd', 'c', 'b', 'a']
None | a | b | c | d | e | f | g | h | None |
---|---|---|---|---|---|---|---|---|---|
? | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
-9 | -8 | -7 | -6 | -5 | -4 | -3 | -2 | -1 | ? |
-1:-9:-1] # 지양 <-- 쓰지마.. lst[
['h', 'g', 'f', 'e', 'd', 'c', 'b', 'a']
B. len함수
-
0차원 자료형은 len함수가 동작하지 않음
=1
alen(a)
TypeError: object of type 'int' has no len()
=True
alen(a)
TypeError: object of type 'bool' has no len()
=3.14
alen(a)
TypeError: object of type 'float' has no len()
note: 이것이 어떠한 수학적인 의미를 가지거나 0차원의 본질적진리를 뜻하는 것은 아님. R에서는 1,3.14,TRUE의 길이가 1로 존재함.
-
1차원 자료형은 len함수가 동작
='guebin'
alen(a)
6
=[1,2,3,4,5,6]
alen(a)
6
=1,2,3,4,5,6
alen(a)
6
=range(10)
alen(a)
10
-
길이가 1인 1차원 자료형과 0차원 자료형은 다른것임
='g'
alen(a)
1
=[1]
alen(a)
1
=(1,)
alen(a)
1
=range(1)
alen(a)
1
-
길이가 0인 1차원 자료형도 존재함
=''
alen(a)
0
=[]
alen(a)
0
=()
alen(a)
0
=range(0)
alen(a)
0
5. dict
A. intro: str, list, tuple 정리
-
str, list, tuple은 모두 시퀀스형이라는 공통점이 있다. \(\to\) 원소의 위치번호로 인덱싱이 가능
= [1,2,3,4] lst
0] # 위치번호=0 lst[
1
-1] # 위치번호=-1 lst[
4
-
str, list, tuple은 차이점도 존재함. 잠깐 정리해보자.
시퀀스형의 카테고리
- 컨테니어형: list, tuple
- 균일형: str
- 가변형: list
- 불변형: tuple, str
표로 정리하면
컨테니어형 | 균일형 | |
---|---|---|
가변형 | list | . |
불변형 | tuple | str |
-
시퀀스형이 아닌 1차원 자료형도 있을까? 원소의 위치번호로 인덱싱이 불가능한 자료형
-
왜 이런게 필요할까?
- 벡터에서 원소를 뽑는것은 정보의 모임에서 정보를 검색하는 것과 같다.
- 정보를
순서
대로 나열한뒤에 그순서
를 이용하여 검색하는 방법은 유용하다. - 하지만 경우에 따라서는
키워드
를 기억해서 그키워드
를 바탕으로 정보에 접근하는 방법이 유용할 수 있다.
카카오톡 대화내용검색
(상황1) 오늘아침
에 와이프가 뭔가
를 카톡으로 부탁했었음. 그런데 그 뭔가가 기억안남.
(상황2) 방학전에
동료교수과 개강이후 저녁약속
을 카톡으로 잡았었음. 그런데 그게 언제인지 기억안남.
-
순서대로 정리된 자료를 검색할때는 시퀀스형이 유리하다. 그런데 키워드로 검색하고 싶을 경우는 딕셔너리 타입이 유리하다.
B. 선언
-
방법1: 가장 일반적
= {'guebin':49, 'hanni':80}
dct dct
{'guebin': 49, 'hanni': 80}
-
방법2: dict()
이용
= dict(guebin=49, hanni=80)
dct dct
{'guebin': 49, 'hanni': 80}
-
방법3: 중첩된 리스트를 만든 뒤에 형태변환
= [['guebin',49],['hanni',80]]
_lst _lst
[['guebin', 49], ['hanni', 80]]
dict(_lst)
{'guebin': 49, 'hanni': 80}
-
방법4: 중첩된 튜플을 만든 뒤에 형태변환
= ('guebin',49), ('hanni',80)
_tpl _tpl
(('guebin', 49), ('hanni', 80))
dict(_tpl)
{'guebin': 49, 'hanni': 80}
C. 원소추출
-
원소의 위치로 추출할 수 없고, key로 추출해야 한다.
= {'guebin':49, 'hanni':80}
dct dct
{'guebin': 49, 'hanni': 80}
guebin의 점수를 추출하고 싶다면?
'guebin'] dct[
49
-
만약에 dict가 아니라 list로 정보를 저장했다면?
(예제) 아래와 같은 리스트에서 guebin의 점수를 추출하고 싶다면?
=[['guebin',49],['hanni',80]]
lst lst
[['guebin', 49], ['hanni', 80]]
(풀이1)
0][1] # guebin의 점수를 출력하란 의미 lst[
49
(풀이2) – 진짜 최악
1] for i in range(len(lst)) if lst[i][0] == 'guebin'] [lst[i][
[49]
(풀이3) – 덜 최악
for name,score in lst if name == 'guebin'] [score
[49]
-
’guebin’의 점수를 추출하는 코드 비교
'guebin'] # 코드1: 단순하고, 가독성있음 dct[
49
0][1] # 코드2: 단순하지만, 가독성이 있는건 아님, 확장성이 없음 lst[
49
1] for i in range(len(lst)) if lst[i][0] =='guebin'] # 코드3: 단순하지도 않고, 가독성도 없음. [lst[i][
[49]
for name,score in lst if name=='guebin' ] # 코드4: 단순하지 않지만, 가독성은 있음 [score
[49]
D. 원소추가, 변경, 삭제
={'guebin':49, 'hanni':80}
dct dct
{'guebin': 49, 'hanni': 80}
-
원소에 접근: guebin의 점수 출력
'guebin'] dct[
49
-
추가: hynn학생의 점수를 추가
'hynn'] = 99 dct[
dct
{'guebin': 49, 'hanni': 80, 'hynn': 99}
-
변경: hanni의 점수를 변경
'hanni'] = 100 dct[
dct
{'guebin': 49, 'hanni': 100, 'hynn': 99}
-
삭제
(방법1)
={'guebin':49, 'hanni':80, 'hynn':99}
dctdel dct['guebin']
dct
{'hanni': 80, 'hynn': 99}
(방법2)
={'guebin':49, 'hanni':80, 'hynn':99}
dct'guebin') dct.pop(
49
dct
{'hanni': 80, 'hynn': 99}
-
참고로 리스트였다면 이러한 삭제작업역시 비효율적이었을 것임
= [['guebin',49],['hanni',80],['hynn',99]]
lst lst
[['guebin', 49], ['hanni', 80], ['hynn', 99]]
guebin의 점수를 삭제하려면?
for name,score in lst if name != 'guebin'] [[name,score]
[['hanni', 80], ['hynn', 99]]
E. 연산
-
하나있어요..
= {'guebin':49, 'hanni':80}
dct dct
{'guebin': 49, 'hanni': 80}
'guebin' in dct
True
'hanni' in dct
True
'hynn' in dct
False
-
in은 사실 다른자료형도 가능했음
(관찰1)
'a' in 'guebin'
False
'b' in 'guebin'
True
'c' in 'guebin'
False
(관찰2)
= 1,2,3
tpl tpl
(1, 2, 3)
1 in tpl
True
4 in tpl
False
(관찰3)
= [['guebin',49],['hanni',80],['hynn',99]]
lst lst
[['guebin', 49], ['hanni', 80], ['hynn', 99]]
'guebin',49] in lst [
True
-
in연산자가 dict형에 사용되면 key를 기준으로 True, False를 판단한다.
F. 딕셔너리 특수기능
(pop)
= {'guebin':49, 'hanni':80}
dct 'hanni')
dct.pop( dct
{'guebin': 49}
(get)
= {'guebin':49, 'hanni':80}
dct dct
{'guebin': 49, 'hanni': 80}
'guebin') dct.get(
49
아래와 같은 기능
'guebin'] dct[
49
미묘한 차이점이 존재함
'hynn'] # hynn이 없어서 키에러 출력, 그런 key는 없다.. dct[
KeyError: 'hynn'
'hynn') # hynn이 없으면 아무것도 출력안함 dct.get(
(keys,values,items)
for k,v in dct.items():
print(k,v)
guebin 49
hanni 80
-
.keys()는 딕셔너리의 키를 리턴한다.
= {'guebin':49, 'hanni':80}
dct dct
{'guebin': 49, 'hanni': 80}
=dct.keys()
_keys _keys
dict_keys(['guebin', 'hanni'])
type(_keys) # 리턴된 자료형은 이상한것임
dict_keys
list(_keys) # 아무튼 그 이상한 자료형도 리스트화 가능
['guebin', 'hanni']
-
.values()는 딕셔너리의 값들을 리턴한다.
= dct.values()
_values _values
dict_values([49, 80])
type(_values)
dict_values
list(_values)
[49, 80]
-
.items()는 딕셔너리의 (키,값)을 리턴한다.
= dct.items()
_items _items
dict_items([('guebin', 49), ('hanni', 80)])
type(_items)
dict_items
list(_items)
[('guebin', 49), ('hanni', 80)]
G. for문과 dict (\(\star\))
= {'guebin': 49, 'hanni': 80}
dct dct
{'guebin': 49, 'hanni': 80}
(예시1)
for k in dct.keys():
print(k)
guebin
hanni
for k in dct:
print(k)
guebin
hanni
- 딕셔너리 그자체도 for문에 넣을 수 있다. 그때는 딕셔너리의 key가 반복된다.
- 결과를 보면 dct 대신에 dct.keys()와 list(dct)를 넣었을때와 결과가 같다.
Note: list(dct) 하면 key만 리턴된다.
(예시2)
for v in dct.values():
print(v)
49
80
(예시3)
for i in dct.items():
print(i)
('guebin', 49)
('hanni', 80)
(예시4)
for k,v in dct.items():
print(k,v)
guebin 49
hanni 80
(예시5) – {}의 중간고사 점수는 {}점 입니다.
for name,score in dct.items():
print(f'{name}의 중간고사 점수는 {score}점 입니다.')
guebin의 중간고사 점수는 49점 입니다.
hanni의 중간고사 점수는 80점 입니다.
H. dict에서 key혹은 value만 뽑아내기
-
예제: 아래의 dict에서 key만 뽑아내고 싶다.
= {'guebin':49, 'hanni':80} dct
(풀이1)
list(dct)
['guebin', 'hanni']
(풀이2)
list(dct.keys())
['guebin', 'hanni']
(풀이3)
for k in dct] [k
['guebin', 'hanni']
(풀이4)
for k,v in dct.items()] [k
['guebin', 'hanni']
-
예제: 아래의 dict에서 value만 뽑아내고 싶다.
= {'guebin':49, 'hanni':80} dct
(풀이1)
list(dct.values())
[49, 80]
(풀이2)
for k in dct] [dct[k]
[49, 80]
(풀이3)
for v in dct.values()] [v
[49, 80]
(풀이4)
for k,v in dct.items()] [v
[49, 80]
6. 딕셔너리를 이용한 치환 (\(\star\))
A. 바꿔치기
# 예제1
– 아래와 같은 리스트를 고려하자.
= ['딸기','사과','바나나','딸기','사과','오토바이','자동차','버스','기차','오토바이','자동차'] lst
다음의 맵핑규칙에 따라서 위의 리스트의 원소를 바꾸어라.
변환전 | 변환후 |
---|---|
딸기 | 과일 |
사과 | 과일 |
바나나 | 과일 |
오토바이 | 탈것 |
자동차 | 탈것 |
버스 | 탈것 |
기차 | 탈것 |
(풀이1)
– elif
를 한번 써본정도의 의미. 추천하는 풀이 X
= []
lst2 for l in lst:
if l=='딸기':
'과일')
lst2.append(elif l=='사과':
'과일')
lst2.append(elif l=='바나나':
'과일')
lst2.append(elif l=='오토바이':
'탈것')
lst2.append(elif l=='자동차':
'탈것')
lst2.append(elif l=='버스':
'탈것')
lst2.append(else:
'탈것') lst2.append(
lst,lst2
(['딸기', '사과', '바나나', '딸기', '사과', '오토바이', '자동차', '버스', '기차', '오토바이', '자동차'],
['과일', '과일', '과일', '과일', '과일', '탈것', '탈것', '탈것', '탈것', '탈것', '탈것'])
(풀이2)
– 코드는 쉽고 편함. dct를 만들기 힘듦.
= {'딸기':'과일','사과':'과일','바나나':'과일','오토바이':'탈것','자동차':'탈것','버스':'탈것','기차':'탈것'}
dct dct
{'딸기': '과일',
'사과': '과일',
'바나나': '과일',
'오토바이': '탈것',
'자동차': '탈것',
'버스': '탈것',
'기차': '탈것'}
for l in lst] [dct[l]
['과일', '과일', '과일', '과일', '과일', '탈것', '탈것', '탈것', '탈것', '탈것', '탈것']
(풀이3)
– 코드가 매우 어려움. dct를 만들기 쉬움.
= {'과일':['딸기','사과','바나나'], '탈것':['오토바이','자동차','버스','기차']}
dct dct
{'과일': ['딸기', '사과', '바나나'], '탈것': ['오토바이', '자동차', '버스', '기차']}
lst
['딸기', '사과', '바나나', '딸기', '사과', '오토바이', '자동차', '버스', '기차', '오토바이', '자동차']
for l in lst for k in dct if l in dct[k]] [k
['과일', '과일', '과일', '과일', '과일', '탈것', '탈것', '탈것', '탈것', '탈것', '탈것']
#
# 예제2
– 아래와 같은 리스트가 있다고 하자.
= list('abcd'*2+'bbb')
lst lst
['a', 'b', 'c', 'd', 'a', 'b', 'c', 'd', 'b', 'b', 'b']
아래의 규칙에 의하여 lst의 각 원소의 값을 바꾸고 싶다고 하자. 이를 구현하는 코드를 작성하라.
변환전 | 변환후 |
---|---|
‘a’ | [1,0,0,0] |
‘b’ | [0,1,0,0] |
‘c’ | [0,0,1,0] |
‘d’ | [0,0,0,1] |
(풀이)
= {'a':[1,0,0,0], 'b':[0,1,0,0], 'c':[0,0,1,0], 'd':[0,0,0,1]}
dct dct
{'a': [1, 0, 0, 0], 'b': [0, 1, 0, 0], 'c': [0, 0, 1, 0], 'd': [0, 0, 0, 1]}
for l in lst] [dct[l]
[[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[0, 0, 0, 1],
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[0, 0, 0, 1],
[0, 1, 0, 0],
[0, 1, 0, 0],
[0, 1, 0, 0]]
# 예제3
– 예제2을 역변환하라. 즉 아래의 리스트를
= [[1, 0, 0, 0],
lst20, 1, 0, 0],
[0, 0, 1, 0],
[0, 0, 0, 1],
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[0, 0, 0, 1],
[0, 1, 0, 0],
[0, 1, 0, 0],
[0, 1, 0, 0]] [
아래와 같이 바꾸라.
'a', 'b', 'c', 'd', 'a', 'b', 'c', 'd', 'b', 'b', 'b'] [
['a', 'b', 'c', 'd', 'a', 'b', 'c', 'd', 'b', 'b', 'b']
(풀이)
– 실패
= {[1,0,0,0]:'a', [0,1,0,0]:'b', [0,0,1,0]:'c', [0,0,0,1]:'d'}
dct dct
TypeError: unhashable type: 'list'
dct의 key에 대응하는것은 불변형만 가능
(풀이1)
= {(1,0,0,0):'a', (0,1,0,0):'b', (0,0,1,0):'c', (0,0,0,1):'d'}
dct dct
{(1, 0, 0, 0): 'a', (0, 1, 0, 0): 'b', (0, 0, 1, 0): 'c', (0, 0, 0, 1): 'd'}
tuple(l)] for l in lst2] [dct[
['a', 'b', 'c', 'd', 'a', 'b', 'c', 'd', 'b', 'b', 'b']
(풀이2)
= {'a':[1,0,0,0], 'b':[0,1,0,0], 'c':[0,0,1,0], 'd':[0,0,0,1]} # 예제2의 dct dct
for l in lst2 for k in dct if dct[k]==l] [k
['a', 'b', 'c', 'd', 'a', 'b', 'c', 'd', 'b', 'b', 'b']
B. 연습문제
# 문제
. 아래와 같은 맵핑을 고려하자.
문자 | 숫자 |
---|---|
a | 0 |
b | 1 |
이를 딕셔너리로 표현하면 아래와 같다.
= {'a':0, 'b':1} dct
위 규칙에 따라서 아래의 리스트의 원소를 문자로 각각 변환하라.
= [1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1] lst
# 출력은 아래와 같아야 한다.
'b', 'a', 'b', 'a', 'b', 'a', 'b', 'b', 'b', 'b', 'a', 'a', 'b', 'a', 'b'] [
(풀이)
for l in lst for k in dct if l == dct[k]] [k
['b', 'a', 'b', 'a', 'b', 'a', 'b', 'b', 'b', 'b', 'a', 'a', 'b', 'a', 'b']
# 문제
. 아래와 같은 맵핑을 고려하자.
월 | 의미 |
---|---|
1,2 | 겨울방학 |
3,4,5,6 | 1학기 |
7,8 | 여름방학 |
9,10,11,12 | 2학기 |
이러한 규칙에 맞게 아래의 리스트를 적절한 문자열로 변환하라.
= [1,2,2,3,4,5,6,7,8,9,9,10,11,12] month
## 출력은 아래와 같아야 한다.
'겨울방학', '겨울방학', '겨울방학', '1학기', '1학기', '1학기', '1학기', '여름방학', '여름방학', '2학기', '2학기', '2학기', '2학기', '2학기'] [
(풀이1)
– 좀 더 추천함
= {'겨울방학':range(1,3), '1학기':range(3,7), '여름방학':range(7,9), '2학기':range(9,13)} dct
for m in month for k in dct if m in dct[k]] [k
['겨울방학',
'겨울방학',
'겨울방학',
'1학기',
'1학기',
'1학기',
'1학기',
'여름방학',
'여름방학',
'2학기',
'2학기',
'2학기',
'2학기',
'2학기']
(풀이2)
– 추천안함
= {1:'겨울방학',2:'겨울방학',3:'1학기',4:'1학기',5:'1학기',6:'1학기',7:'여름방학',8:'여름방학',9:'2학기',10:'2학기',11:'2학기',12:'2학기'} dct
for m in month] [dct[m]
['겨울방학',
'겨울방학',
'겨울방학',
'1학기',
'1학기',
'1학기',
'1학기',
'여름방학',
'여름방학',
'2학기',
'2학기',
'2학기',
'2학기',
'2학기']
##
– 합성변환
아래와 같은 맵핑을 고려하자.
(규칙1)
문자 | 숫자 |
---|---|
바나나 | 0 |
사과 | 1 |
오토바이 | 2 |
자동차 | 3 |
자전거 | 4 |
(규칙2)
아이템 | 카테고리 |
---|---|
바나나 | 과일 |
사과 | 과일 |
오토바이 | 탈것 |
자동차 | 탈것 |
자전거 | 탈것 |
각각의 규칙을 나타내는 딕셔너리는 아래와 같이 선언되어있다고 하자.
= {'바나나':0, '사과':1, '오토바이':2, '자동차':3, '자전거':4}
dct1 = {'과일':['바나나','사과'], '탈것':['오토바이','자동차','자전거']} dct2
# 문제
. 규칙1를 이용하여 아래와 같은 리스트를 변환하는 함수를 구현하고 그 함수를 f
라 선언하라.
# 입력
0,1,0,1,4]
[
# 출력
'바나나', '사과', '바나나', '사과', '자전거'] [
(사용예시)
0,1,0,1,4]) f([
['바나나', '사과', '바나나', '사과', '자전거']
(풀이)
= lambda lst: [k for l in lst for k in dct1 if l == dct1[k]] f
0,1,0,1,4]) f([
['바나나', '사과', '바나나', '사과', '자전거']
# 문제
. 규칙2를 이용하여 아래와 같이 리스트를 변환하는 함수를 구현하고 그 함수를 g
라고 선언하라.
# 입력
'바나나','바나나','바나나','자동차']
[
# 출력
'과일','과일','과일','탈것'] [
(사용예시)
'바나나','바나나','바나나','자동차']) g([
['과일', '과일', '과일', '탈것']
(풀이)
= lambda lst: [k for l in lst for k in dct2 if l in dct2[k]] g
'바나나','바나나','바나나','자동차']) g([
['과일', '과일', '과일', '탈것']
# 문제
. 규칙1-2를 이용하여 아래와 같은 숫자로 이루어진 입력을 ‘과일’, ‘탈것’ 중 하나로 바꾸는 코드를 구현하라.
# 입력
0,1,0,1,3,4,2,2,3,4,1,0]
[
# 출력
'과일', '과일', '과일', '과일', '탈것', '탈것', '탈것', '탈것', '탈것', '탈것', '과일', '과일'] [
hint \(g(f(x))\) 를 이용하라.
(풀이)
0,1,0,1,3,4,2,2,3,4,1,0])) g(f([
['과일', '과일', '과일', '과일', '탈것', '탈것', '탈것', '탈것', '탈것', '탈것', '과일', '과일']
7. 파이썬 자료형 연습문제
Oxford-III
: // reference
아래는 이미지 파일명들이 저장된 string을 불러오는 코드이다.
import requests
= 'https://raw.githubusercontent.com/guebin/PP2023/main/posts/01_PythonBasic/Oxford-IIIT.txt'
url = requests.get(url).content.decode() txt
txt의 출력 일부를 나타내면 아래와 같다.
'Abyssinian_1.jpg\nAbyssinian_10.jpg\nAbyssinian_100.jpg\nAbyssinian_100.mat\nAbyssinian_101.jpg\nAbyssinian_101.mat\nAbyssinian_102.jpg\nAbyssinian_102.mat\nAbyssinian_103.jpg\nAbyssinian_104.jpg\nAbyssinian_105.jpg\nAbyssinian_106.jpg\nAbyssinian_107.jpg\nAbyssinian_108.jpg\nAbyssinian_109.jpg\nAbyssinian_11.jpg\nAbyssinian_110.jpg\nAbyssinian_111.jpg\nAbyssinian_112.jpg\nAbyssinian_113.jpg\nAbyssinian_114.jpg\nAbyssinian_115.jpg\nAbyssinian_116.jpg\nAbyssinian_117.jpg\nAbyssinian_118.jpg\nAbyssinian_119.jpg\nAbyssinian_12.jpg\nAbyssinian_120.jpg\nAbyssinian_121.jpg\nAbyssinian_122.jpg\nAbyssinian_123.jpg\nAbyssinian_124.jpg\nAbyssinian_125.jpg\nAbyssinian_126.jpg\nAbyssinian_127.jpg\nAbyssinian_128.jpg\nAbyssinian_129.jpg\nAbyssinian_13.jpg\nAbyssinian_130.jpg\nAbyssinian_131.jpg\nAbyssinian_132.jpg\n .......
# 문제
. 각 파일명은 \n
으로 구분되어있다. 위의 스트링을 분해하여 아래와 같은 리스트를 생성하고 fname_list
에 저장하라.
# fname_list 의 출력결과는 아래와 같아야 한다.
'Abyssinian_1.jpg','Abyssinian_10.jpg', ... ,'yorkshire_terrier_98.jpg', 'yorkshire_terrier_99.jpg'] [
(풀이)
= txt.split('\n')
fname_list 5] # 7393개의 이미지파일명이 저장되어있음. fname_list[:
['Abyssinian_1.jpg',
'Abyssinian_10.jpg',
'Abyssinian_100.jpg',
'Abyssinian_100.mat',
'Abyssinian_101.jpg']
# 문제
. 각 이미지파일명은 아래와 같은 규칙으로 저장되어 있다.
- 파일명의 첫글자가 대문자이면 고양이를 의미하고 첫글자가 소문자이면 강아지를 의미한다.
이미지 파일명이 입력으로 오면 강아지인지 고양이인지 판단하여 ‘cat’ or ’dog’를 리턴하는 함수 f
를 구현하라.
(함수사용예시)
'yorkshire_terrier_99.jpg') f(
'dog'
'Abyssinian_1.jpg') f(
'cat'
(풀이)
= lambda s: 'cat' if s[0].isupper() else 'dog'
f 'Abyssinian_1.jpg') f(
'cat'
# 문제
. 위의 결과로 나온 fname_list
를 입력으로 하고 리스트의 각 원소가 고양이를 의미하는 그림인지 강아지를 의미하는 그림인지 나타내는 리스트를 만들어라.
## 입력예시
'Abyssinian_1.jpg','Abyssinian_10.jpg',...,'yorkshire_terrier_98.jpg', 'yorkshire_terrier_99.jpg']
[
## 출력예시
'cat', 'cat', ... , 'dog', 'dog'] [
(풀이1)
#list(map(f,fname_list))
(풀이2)
#[f(fname) for fname in fname_list]
# 문제
. 강아지 그림과 고양이 그림이 각각 몇 장씩 포함되어 있는지 파악하는 코드를 구현하라.
(풀이)
for fname in fname_list].count('cat') [f(fname)
2403
for fname in fname_list].count('dog') [f(fname)
4990
# 문제
. 고양이 혹은 강아지의 각 종이 몇 장씩 포함되어있는지 구하여 딕셔너리로 정리하라.
(풀이)
= ['_'.join(l.split('_')[:-1]) for l in fname_list]
lst for s in set(lst)} {s:lst.count(s)
{'yorkshire_terrier': 200,
'Siamese': 200,
'chihuahua': 200,
'Persian': 200,
'miniature_pinscher': 200,
'samoyed': 200,
'boxer': 200,
'american_pit_bull_terrier': 200,
'german_shorthaired': 200,
'great_pyrenees': 200,
'Sphynx': 200,
'shiba_inu': 200,
'american_bulldog': 200,
'havanese': 200,
'Bombay': 200,
'japanese_chin': 200,
'Ragdoll': 200,
'english_cocker_spaniel': 200,
'english_setter': 200,
'Egyptian_Mau': 200,
'staffordshire_bull_terrier': 191,
'Russian_Blue': 200,
'beagle': 200,
'pomeranian': 200,
'British_Shorthair': 200,
'pug': 200,
'Bengal': 200,
'newfoundland': 200,
'wheaten_terrier': 200,
'Abyssinian': 203,
'Maine_Coon': 200,
'basset_hound': 200,
'saint_bernard': 200,
'scottish_terrier': 199,
'keeshond': 200,
'leonberger': 200,
'Birman': 200}