04wk-1: 파이썬의 자료형 (6)

Author

최규빈

Published

March 27, 2023

강의영상

youtube: https://youtube.com/playlist?list=PLQqh36zP38-yH_F4QH9ldMXyEDA5wWXx_

  • 강의 마지막에 집합 설명하려다가 다 못했습니다. 집합은 다음시간에 다시 설명하겠습니다. 위 영상에서 집합설명한 부분은 무시하셔도 됩니다.

잡기술 (하지만 유용해)

인덱싱고급 (스트라이딩)

- 스트라이딩 [start:end:step]

lst = list('abcdefghijk')
lst
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k']
lst[0:9:3]
['a', 'd', 'g']

- 생략

lst[0:9]
#lst[0:9:]
#lst[0:9:1]
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']
lst[0::3]
['a', 'd', 'g', 'j']
lst[:8:3]
['a', 'd', 'g']

- 예제1: 짝수/홀수 원소 추출

아래와 같은 문자열이 있다고 하자.

lst = list('abcdefghijk')
lst
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k']

index = 0,2,4, ... 에 해당하는 원소를 출력하라.

lst[::2]
['a', 'c', 'e', 'g', 'i', 'k']

index = 1,4,7 ... 에 해당하는 원소를 출력하라.

lst[1::3]
['b', 'e', 'h', 'k']

- 예제2: 세로로..


(예제2를 위한 예비학습) 문자열에서 \n을 출력하면 출력시 줄바꿈이 일어난다.

print('1행\n2행\n3행')
1행
2행
3행

예비학습 끝


아래와 같은 문자열이 있다고 하자.

txt = '너같이사랑스럽고\n또예쁘고도멋지고\n속훤히보이는너알\n았어그동안고마웠\n지정말정말사랑해'
print(txt)
너같이사랑스럽고
또예쁘고도멋지고
속훤히보이는너알
았어그동안고마웠
지정말정말사랑해

위 문자열을 세로로 읽는 코드를 작성하라. (9칸씩 점프하면서 읽으면 된다)

(풀이)

txt[::9]
'너또속았지'

- step = -1 이면?

lst
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k']
lst[::-1]
['k', 'j', 'i', 'h', 'g', 'f', 'e', 'd', 'c', 'b', 'a']

- 스트라이딩으로 step = -1 옵션 주기 vs 리스트의 .reverse() 메소드 이용하기

관찰1: reverse 메소드는 리스트 자체를 변화시킴

lst = list('abcdefgh')
lst
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
lst.reverse()  
lst
['h', 'g', 'f', 'e', 'd', 'c', 'b', 'a']

관찰2: [::-1]는 리스트는 변화시키지 않음

lst = list('abcdefgh')
lst
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
lst[::-1]
['h', 'g', 'f', 'e', 'd', 'c', 'b', 'a']
lst
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']

- -step은 쓰기 까다롭다.

(예제) 처음과 끝을 생략하지 않고 아래와 동일한 효과를 주는 코드를 만들어 보자.

lst = list('abcdefgh')
lst[::-1]
['h', 'g', 'f', 'e', 'd', 'c', 'b', 'a']

(풀이)

결국 lst[?:?:-1]의 꼴에서 적당히 ?의 값을 채우면 된다. –> 어려워

lst
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
lst[::-1]
['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 ?
lst[-1:-9:-1] 
['h', 'g', 'f', 'e', 'd', 'c', 'b', 'a']

컴프리헨션 고급 (if문이 포함된 컴프리헨션)

- 예제: 제곱수중에서 12로 나누어 떨어지는 수만 원소로 가지는 리스트를 만들고 싶다.

  • 제곱수: 1,4,9,16,25,36, …
  • 12로 나누어 떨어지는 수: 36, …

(예비학습1)

12 % 4 # %는 나머지를 계산하는 연산자, 12를 4로 나누면 나머지가 0
0
12 % 5 # %는 나머지를 계산하는 연산자, 12를 5로 나누면 나머지가 2
2

(예비학습2)

a = 2 ## a에 2를 "대입" 하라. 
a == 2 # a에 들어있는 값이 2인지 "test"하라.
True
a == 3 # a에 들어있는 값이 3인지 "test"하라.
False

(예비학습3) if문

a= 3 
if a%2 == 0: 
    a_is='even' ## a%2==0 이 true일 경우만 실행된다. 
else:
    a_is='odd' ## a%2==0 이 false일 경우만 실행된다. 
a,a_is
(3, 'odd')

(풀이1) - 비어있는 리스트를 만들고 \(\to\) for문 + if문

lst = list()
for i in range(1,101): 
    if i**2 % 12 == 0:
        lst.append(i**2)
lst
[36,
 144,
 324,
 576,
 900,
 1296,
 1764,
 2304,
 2916,
 3600,
 4356,
 5184,
 6084,
 7056,
 8100,
 9216]

(풀이2) - if문이 포함된 리스트컴프리헨션

[i**2 for i in range(1,101) if i**2 % 12 == 0]
[36,
 144,
 324,
 576,
 900,
 1296,
 1764,
 2304,
 2916,
 3600,
 4356,
 5184,
 6084,
 7056,
 8100,
 9216]

함수고급 (if문이 포함된 리턴)

- 홀수/짝수를 판별하는 함수 만들기 1

def test(x): 
    if x % 2 == 0: 
        return 'even'
    else:
        return 'odd'
test(5)
'odd'

(사용)

[test(l) for l in list(range(1,11))]
['odd', 'even', 'odd', 'even', 'odd', 'even', 'odd', 'even', 'odd', 'even']

- 홀수/짝수를 판별하는 함수 만들기 2

def test(x):
    return 'even' if x % 2 == 0 else 'odd'
test(4)
'even'

(사용)

[test(l) for l in list(range(1,11))]
['odd', 'even', 'odd', 'even', 'odd', 'even', 'odd', 'even', 'odd', 'even']

len함수

- 0차원 자료형은 len함수가 동작하지 않음

a=1 
len(a)
TypeError: object of type 'int' has no len()
a=True
len(a)
TypeError: object of type 'bool' has no len()
a=3.14
len(a)
TypeError: object of type 'float' has no len()

note: 이것이 어떠한 수학적인 의미를 가지거나 0차원의 본질적진리를 뜻하는 것은 안미. R에서는 1,3.14,TRUE의 길이가 1로 존재함.

- 1차원 자료형은 len함수가 동작

a='guebin'
len(a)
6
a=[1,2,3,4,5,6]
len(a)
6
a=1,2,3,4,5,6 
len(a)
6
a=range(10)
len(a)
10

- 길이가 1인 1차원 자료형과 0차원 자료형은 다른것임

a='g'
len(a)
1
a=[1]
len(a)
1
a=(1,)
len(a)
1
a=range(1)
len(a)
1

- 길이가 0인 1차원 자료형도 존재함

a=''
len(a)
0
a=[]
len(a)
0
a=()
len(a)
0
a=range(0)
len(a)
0

딕셔너리 기본내용

intro: str, list, tuple 정리

- str, list, tuple은 모두 시퀀스형이라는 공통점이 있다. \(\to\) 원소의 위치번호로 인덱싱이 가능

lst = [1,2,3,4]
lst[0] # 위치번호=0
1
lst[-1] # 위치번호=-1
4

- str, list, tuple은 차이점도 존재함. 잠깐 정리해보자.

시퀀스형의 카테고리

  • 컨테니어형: list, tuple
  • 균일형: str
  • 가변형: list
  • 불변형: tuple, str

표로 정리하면

컨테니어형 균일형
가변형 list .
불변형 tuple str

- 시퀀스형이 아닌 1차원 자료형도 있을까? 원소의 위치번호로 인덱싱이 불가능한 자료형

- 왜 이런게 필요할까?

  • 벡터에서 원소를 뽑는것은 정보의 모임에서 정보를 검색하는 것과 같다.
  • 정보를 순서대로 나열한뒤에 그 순서를 이용하여 검색하는 방법은 유용하다.
  • 하지만 경우에 따라서는 키워드를 기억해서 그 키워드를 바탕으로 정보에 접근하는 방법이 유용할 수 있다.

카카오톡 대화내용검색

(상황1) 오늘아침에 와이프가 뭔가를 카톡으로 부탁했었음. 그런데 그 뭔가가 기억안남.

(상황2) 개강전에 동료교수와 함께 저녁약속을 카톡으로 잡았었음. 그런데 그게 언제인지 기억안남.

(상황3) 오늘아침 동료교수와 함께 점심약속을 카톡으로 잡았었음. 그런데 그 장소가 기억나지 않음.

- 순서대로 정리된 자료를 검색할때는 시퀀스형이 유리하다. 그런데 키워드로 검색하고 싶을 경우는 딕셔너리 타입이 유리하다.

선언

- 방법1: 가장 일반적

dct = {'guebin':49, 'hanni':80}
dct
{'guebin': 49, 'hanni': 80}

- 방법2: dict() 이용

dct = dict(guebin=49, hanni=80)
dct
{'guebin': 49, 'hanni': 80}

- 방법3: 중첩된 리스트를 만든 뒤에 형태변환

_lst = [['guebin',49],['hanni',80]]
_lst 
[['guebin', 49], ['hanni', 80]]
dict(_lst)
{'guebin': 49, 'hanni': 80}

- 방법4: 중첩된 튜플을 만든 뒤에 형태변환

_tpl = ('guebin',49), ('hanni',80)
_tpl
(('guebin', 49), ('hanni', 80))
dict(_tpl)
{'guebin': 49, 'hanni': 80}

원소추출

- 원소의 위치로 추출할 수 없고, key로 추출해야 한다.

dct = {'guebin':49, 'hanni':80}
dct
{'guebin': 49, 'hanni': 80}

guebin의 점수를 추출하고 싶다면?

dct['guebin']
49

- 만약에 dict가 아니라 list로 정보를 저장했다면?

(예제) 아래와 같은 리스트에서 guebin의 점수를 추출하고 싶다면?

lst=[['guebin',49],['hanni',80]]
lst
[['guebin', 49], ['hanni', 80]]

(풀이1)

lst[0][1] # guebin의 점수를 출력하란 의미
49

(풀이2) – 진짜 최악

[lst[i][1] for i in range(len(lst)) if lst[i][0] == 'guebin']
[49]

(풀이3) – 덜 최악

[score for name,score in lst if name == 'guebin']
[49]

- ’guebin’의 점수를 추출하는 코드 비교

dct['guebin'] # 코드1: 단순하고, 가독성있음
49
lst[0][1] # 코드2: 단순하지만, 가독성이 있는건 아님
49
[lst[i][1] for i in range(len(lst)) if lst[i][0] =='guebin'] # 코드3: 단순하지도 않고, 가독성도 없음.
[49]
[score for name,score in lst if name=='guebin' ] # 코드4: 단순하지 않지만, 가독성은 있음
[49]

원소추가, 변경, 삭제

dct={'guebin':49, 'hanni':80}
dct
{'guebin': 49, 'hanni': 80}

- 원소에 접근: guebin의 점수 출력

dct['guebin']
49

- 추가: hynn학생의 점수를 추가

dct['hynn'] = 99
dct
{'guebin': 49, 'hanni': 80, 'hynn': 99}

- 변경: hanni의 점수를 변경

dct['hanni'] = 100 
dct
{'guebin': 49, 'hanni': 100, 'hynn': 99}

- 삭제

(방법1)

dct={'guebin':49, 'hanni':80, 'hynn':99}
del dct['guebin']  
dct
{'hanni': 80, 'hynn': 99}

(방법2)

dct={'guebin':49, 'hanni':80, 'hynn':99} 
dct.pop('guebin')
49
dct
{'hanni': 80, 'hynn': 99}

- 참고로 리스트였다면 이러한 삭제작업역시 비효율적이었을 것임

lst = [['guebin',49],['hanni',80],['hynn',99]] 
lst
[['guebin', 49], ['hanni', 80], ['hynn', 99]]

guebin의 점수를 삭제하려면?

[[name,score] for name,score in lst if name != 'guebin']
[['hanni', 80], ['hynn', 99]]

연산

- 하나있어요..

dct = {'guebin':49, 'hanni':80} 
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)

tpl = 1,2,3 
tpl
(1, 2, 3)
1 in tpl
True
4 in tpl
False

(관찰3)

lst = [['guebin',49],['hanni',80],['hynn',99]] 
lst
[['guebin', 49], ['hanni', 80], ['hynn', 99]]
['guebin',49] in lst
True

- in연산자가 dict형에 사용되면 key를 기준으로 True, False를 판단한다.

딕셔너리 특수기능

(pop)

dct = {'guebin':49, 'hanni':80} 
dct.pop('hanni')
dct
{'guebin': 49}

(get)

dct = {'guebin':49, 'hanni':80} 
dct
{'guebin': 49, 'hanni': 80}
dct.get('guebin') 
49

아래와 같은 기능

dct['guebin']
49

미묘한 차이점이 존재함

dct['hynn'] # hynn이 없어서 키에러 출력, 그런 key는 없다.. 
KeyError: 'hynn'
dct.get('hynn') # hynn이 없으면 아무것도 출력안함 

(keys,values,items)

- .keys()는 딕셔너리의 키를 리턴한다.

dct = {'guebin':49, 'hanni':80} 
dct
{'guebin': 49, 'hanni': 80}
_keys=dct.keys()
_keys
dict_keys(['guebin', 'hanni'])
type(_keys) # 리턴된 자료형은 이상한것임
dict_keys
list(_keys) # 아무튼 그 이상한 자료형도 리스트화 가능 
['guebin', 'hanni']

- .values()는 딕셔너리의 값들을 리턴한다.

_values = dct.values()
_values 
dict_values([49, 80])
type(_values)
dict_values
list(_values)
[49, 80]

- .items()는 딕셔너리의 (키,값)을 리턴한다.

_items = dct.items()
_items 
dict_items([('guebin', 49), ('hanni', 80)])
type(_items)
dict_items
list(_items)
[('guebin', 49), ('hanni', 80)]

for문과 dict (\(\star\))

dct = {'guebin': 49, 'hanni': 80}
dct
{'guebin': 49, 'hanni': 80}

(예시1)

for k in dct.keys():
    print(k)
guebin
hanni
for k in dct:
    print(k)
guebin
hanni
  • 딕셔너리 그자체도 for문에 넣을 수 있다.
  • k에는 value가 삭제되어 들어간다. (즉 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('{}의 중간고사 점수는 {}점 입니다.'.format(name,score))
guebin의 중간고사 점수는 49점 입니다.
hanni의 중간고사 점수는 80점 입니다.

딕셔너리 고급내용 (1) (\(\star\))

dict에서 key혹은 value만 뽑아내기

- 예제: 아래의 dict에서 key만 뽑아내고 싶다.

dct = {'guebin':49, 'hanni':80} 

(풀이1)

list(dct)
['guebin', 'hanni']

(풀이2)

list(dct.keys())
['guebin', 'hanni']

(풀이3)

[k for k in dct]
['guebin', 'hanni']

(풀이4)

[k for k,v in dct.items()]
['guebin', 'hanni']

- 예제: 아래의 dict에서 value만 뽑아내고 싶다.

dct = {'guebin':49, 'hanni':80} 

(풀이1)

list(dct.values())
[49, 80]

(풀이2)

[dct[k] for k in dct]
[49, 80]

(풀이3)

[v for v in dct.values()]
[49, 80]

(풀이4)

[v for k,v in dct.items()]
[49, 80]

바꿔치기 (1)

- 예제1: 아래와 같은 리스트가 있다고 하자.

lst = list('abcd'*2)
lst
['a', 'b', 'c', 'd', 'a', 'b', 'c', 'd']

아래의 규칙에 의하여 lst의 각 원소의 값을 바꾸고 싶다고 하자. 이를 구현하는 코드를 작성하라.

변환전 변환후
‘a’ [1,0,0,0]
‘b’ [0,1,0,0]
‘c’ [0,0,1,0]
‘d’ [0,0,0,1]

hint: 아래의 dct를 이용할 것

lst = list('abcd'*2)
lst
['a', 'b', 'c', 'd', 'a', 'b', 'c', 'd']
dct = {'a':[1,0,0,0], 'b':[0,1,0,0], 'c':[0,0,1,0], 'd':[0,0,0,1]}
dct
{'a': [1, 0, 0, 0], 'b': [0, 1, 0, 0], 'c': [0, 0, 1, 0], 'd': [0, 0, 0, 1]}

(풀이)

[dct[x] for x in lst]
[[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]]

- 예제2: 예제1을 역변환하라.

dct = {'a':[1,0,0,0], 'b':[0,1,0,0], 'c':[0,0,1,0], 'd':[0,0,0,1]}
lst= [[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]]
lst 
[[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]]

(풀이)

[x for l in lst for x,y in dct.items() if y == l]
['a', 'b', 'c', 'd', 'a', 'b', 'c', 'd']

바꿔치기 (2)

- 예제1: 아래와 같은 리스트를 고려하자.

lst = ['딸기','사과','바나나','딸기','사과','오토바이','자동차','버스','기차','오토바이','자동차']

다음의 맵핑규칙에 따라서 위의 리스트의 원소를 바꾸어라.

변환전 변환후
딸기 과일
사과 과일
바나나 과일
오토바이 탈것
자동차 탈것
버스 탈것
기차 탈것

(풀이)

dct = {'과일':['딸기','사과','바나나'], '탈것':['오토바이','자동차','버스','기차']}
dct
{'과일': ['딸기', '사과', '바나나'], '탈것': ['오토바이', '자동차', '버스', '기차']}
[x for l in lst for x,y in dct.items() if l in y]
['과일', '과일', '과일', '과일', '과일', '탈것', '탈것', '탈것', '탈것', '탈것', '탈것']

HW 0327 (1)

ssh코드: 1-2

아래의 문자열을 고려하자.

test_arr = 'ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAklOUpkDHrfHY17SbrmTIpNLTGK9Tjom/BWDSUGPl+nafzlHDTYW7hdI4yZ5ew18JH4JW9jbhUFrviQzM7xlELEVf4h9lFX5QVkbPppSwg0cda3Pbv7kOdJ/MTyBlWXFCR+HAo3FXRitBqxiX1nKhXpHAZsMciLq8V6RjsNAQwdsdMFvSlVK/7XAt3FaoJoAsncM1Q9x5+3V0Ww68/eIFmb1zuUFljQJKprrX88XypNDvjYNby6vw/Pb0rwert/EnmZ+AW4OZPnTPI89ZPmVMLuayrD2cE86Z/il8b+gw3r3+1nKatmIkjn2so1d01QraTlMqVSsbxNrRFi9wrf+M7Q== schacon@mylaptop.local'

1. 이 문자열에서 index = 0,2,4,6,8,... 에 해당하는 원소를 출력하는 코드를 작성하라. (2022-파이썬입문 중간고사 1-(2) 참고)

# 출력결과는 아래와 같아야 한다. 
'shraAABNa1cEAAIAAEkOpDrH1SrTpLG9jmBDUP+azHTWhIy5w8HJ9bUriz7lLV49F5VbpSgcaPvkd/TBWFRHoFRtqi1KXHZMiqVRsAwsMvlK7A3aJAnMQx+VW6/Im1uFjJpr8XpDjNyv/bretEm+WOPTI9PVLar2E6/lbg331KtIj2od1rTMVsxrF9r+7= cao@yatplcl'

(풀이)

test_arr[::2]
'shraAABNa1cEAAIAAEkOpDrH1SrTpLG9jmBDUP+azHTWhIy5w8HJ9bUriz7lLV49F5VbpSgcaPvkd/TBWFRHoFRtqi1KXHZMiqVRsAwsMvlK7A3aJAnMQx+VW6/Im1uFjJpr8XpDjNyv/bretEm+WOPTI9PVLar2E6/lbg331KtIj2od1rTMVsxrF9r+7= cao@yatplcl'

2. 위 문자열을 뒤집은 문자열을 구하는 코드를 구현하라. (2022-파이썬입문 중간고사 1-(4) 참고)

# 출력결과는 아래와 같아야 한다. 
'lacol.potpalym@nocahcs ==Q7M+frw9iFRrNxbsSVqMlTarQ10d1os2njkImtaKn1+3r3wg+b8li/Z68Ec2DryauLMVmPZ98IPTnPZO4WA+ZmnE/trewr0bP/wv6ybNYjvDNpyX88XrrpKJQjlFUuz1bmFIe/86wW0V3+5x9Q1McnsAoJoaF3tAX7/KVlSvFMdsdwQANsjR6V8qLicMsZAHpXhKn1XixqBtiRXF3oAH+RCFXWlByTM/JdOk7vbP3adc0gwSppPbkVQ5XFl9h4fVELElx7MzQivrFUhbj9WJ4HJ81we5Zy4Idh7WYTDHlzfan+lPGUSDWB/mojT9KGTLNpITmrbS71YHfrHDkpUOlkAEQAAAwIBAAAAE2cy1CazN3BAAAA asr-hss'

(풀이)

test_arr[::-1]
'lacol.potpalym@nocahcs ==Q7M+frw9iFRrNxbsSVqMlTarQ10d1os2njkImtaKn1+3r3wg+b8li/Z68Ec2DryauLMVmPZ98IPTnPZO4WA+ZmnE/trewr0bP/wv6ybNYjvDNpyX88XrrpKJQjlFUuz1bmFIe/86wW0V3+5x9Q1McnsAoJoaF3tAX7/KVlSvFMdsdwQANsjR6V8qLicMsZAHpXhKn1XixqBtiRXF3oAH+RCFXWlByTM/JdOk7vbP3adc0gwSppPbkVQ5XFl9h4fVELElx7MzQivrFUhbj9WJ4HJ81we5Zy4Idh7WYTDHlzfan+lPGUSDWB/mojT9KGTLNpITmrbS71YHfrHDkpUOlkAEQAAAwIBAAAAE2cy1CazN3BAAAA asr-hss'

파이썬 프로그래밍 시험성적: 3-4

아래와 같은 dictionary가 있다고 가정하자.

dct={'202212377': {'att': 65, 'rep': 45, 'mid': 0, 'fin': 10},
     '202212473': {'att': 95, 'rep': 30, 'mid': 60, 'fin': 10},
     '202212310': {'att': 65, 'rep': 85, 'mid': 15, 'fin': 20},
     '202212460': {'att': 55, 'rep': 35, 'mid': 35, 'fin': 5},
     '202212320': {'att': 80, 'rep': 60, 'mid': 55, 'fin': 70},
     '202212329': {'att': 75, 'rep': 40, 'mid': 75, 'fin': 85},
     '202212408': {'att': 65, 'rep': 70, 'mid': 60, 'fin': 75},
     '202212319': {'att': 60, 'rep': 25, 'mid': 20, 'fin': 35},
     '202212348': {'att': 95, 'rep': 55, 'mid': 65, 'fin': 90},
     '202212306': {'att': 90, 'rep': 25, 'mid': 95, 'fin': 50},
     '202212308': {'att': 55, 'rep': 45, 'mid': 75, 'fin': 30},
     '202212366': {'att': 95, 'rep': 60, 'mid': 25, 'fin': 55},
     '202212367': {'att': 95, 'rep': 35, 'mid': 0, 'fin': 25},
     '202212461': {'att': 50, 'rep': 55, 'mid': 90, 'fin': 45}}

여기에서 ‘202212377’ 등은 학번을, att는 출석점수, rep는 레포트점수, mid는 중간고사 점수, fin은 기말고사 점수를 의미한다.

3. 학생들의 학번을 아래와 같은 방식으로 출력하는 코드를 작성하라.

# 출력예시
['2022-12377',
 '2022-12473',
 '2022-12310',
 '2022-12460',
 '2022-12320',
 '2022-12329',
 '2022-12408',
 '2022-12319',
 '2022-12348',
 '2022-12306',
 '2022-12308',
 '2022-12366',
 '2022-12367',
 '2022-12461']

(풀이)

[k[:4]+'-'+k[4:] for k in dct]
['2022-12377',
 '2022-12473',
 '2022-12310',
 '2022-12460',
 '2022-12320',
 '2022-12329',
 '2022-12408',
 '2022-12319',
 '2022-12348',
 '2022-12306',
 '2022-12308',
 '2022-12366',
 '2022-12367',
 '2022-12461']

4. 출석점수가 70점 이상인(>=70) 학생들의 학번을 출력하는 코드를 작성하라. (2022-파이썬입문 중간고사 2-(3) 참고)

# 출력예시 
['2022-12473',
 '2022-12320',
 '2022-12329',
 '2022-12348',
 '2022-12306',
 '2022-12366',
 '2022-12367']

(풀이)

[k[:4]+'-'+k[4:] for k,v in dct.items() if v['att']>70]
['2022-12473',
 '2022-12320',
 '2022-12329',
 '2022-12348',
 '2022-12306',
 '2022-12366',
 '2022-12367']

Oxford-III: 5–10 // reference

아래는 이미지 파일명들이 저장된 string을 불러오는 코드이다.

import requests
url = 'https://raw.githubusercontent.com/guebin/PP2023/main/posts/01_PythonBasic/Oxford-IIIT.txt'
txt = requests.get(url).content.decode()

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 ....... 

5. 각 파일명은 \n으로 구분되어있다. 위의 스트링을 분해하여 아래와 같은 리스트를 생성하고 fname_list에 저장하라.

# fname_list 의 출력결과는 아래와 같아야 한다. 
['Abyssinian_1.jpg','Abyssinian_10.jpg', ... ,'yorkshire_terrier_98.jpg', 'yorkshire_terrier_99.jpg']

(풀이)

fname_list = txt.split('\n')
fname_list[:10]
['Abyssinian_1.jpg',
 'Abyssinian_10.jpg',
 'Abyssinian_100.jpg',
 'Abyssinian_100.mat',
 'Abyssinian_101.jpg',
 'Abyssinian_101.mat',
 'Abyssinian_102.jpg',
 'Abyssinian_102.mat',
 'Abyssinian_103.jpg',
 'Abyssinian_104.jpg']

6. 각 이미지파일명은 아래와 같은 규칙으로 저장되어 있다.

  • 파일명의 첫글자가 대문자이면 고양이를 의미하고 첫글자가 소문자이면 강아지를 의미한다.
  • _ 이전의 영문명은 고양이 혹은 강아지의 종(breed)을 의미한다.

이미지 파일명이 입력으로 오면 강아지인지 고양이인지 판단하여 ‘cat’ or ’dog’를 리턴하는 함수 f를 구현하라.

(함수사용예시)

f('yorkshire_terrier_99.jpg')
'dog'
f('Abyssinian_1.jpg')
'cat'

(풀이)

def f(fname): 
    return 'cat' if fname[0].isupper() else 'dog' 
f('yorkshire_terrier_99.jpg'), f('Abyssinian_1.jpg')
('dog', 'cat')

7. 5의 결과로 나온 fname_list를 입력으로 하고 리스트의 각 원소가 고양이를 의미하는 그림인지 강아지를 의미하는 그림인지 나타내는 리스트를 만들어라.

## 입력예시 
['Abyssinian_1.jpg','Abyssinian_10.jpg',...,'yorkshire_terrier_98.jpg', 'yorkshire_terrier_99.jpg']

## 출력예시
['cat', 'cat', ... , 'dog', 'dog']

(풀이)

result = [f(l) for l in fname_list]
result[:10]
['cat', 'cat', 'cat', 'cat', 'cat', 'cat', 'cat', 'cat', 'cat', 'cat']

8. 강아지 그림과 고양이 그림이 각각 몇 장씩 포함되어 있는지 파악하는 코드를 구현하라.

(풀이)

sum([s=='cat' for s in result]) # 고양이
2403
sum([s=='dog' for s in result]) # 강아지
4990

9. 포메라니안 종의 그림이 몇장있는지 파악하는 코드를 구현하라.

hint: 포메라니안 그림은 파일명에 ‘pomeranian’ 을 포함한다.

(풀이)

sum(['pomeranian'  in s for s in fname_list])
200

10. 아래의 dct는 포메라니안과 사모예드가 각각 몇장씩 포함되어있는지 정리하기 위해 임시로 정리한 dictionary이다. 각 종이 몇 장씩 포함되어있는지 구하여 dct를 수정하라.

dct = {'pomeranian':0, 'samoyed':0} 
dct
{'pomeranian': 0, 'samoyed': 0}

예를들어 포메라니안과 사모에예드의 그림이 각각 200장씩 있다면 아래와 같이 딕셔너리를 수정해야한다.

{'pomeranian':200, 'samoyed':200} 
{'pomeranian': 200, 'samoyed': 200}

(풀이)

dct['pomeranian'] = sum(['pomeranian'  in s for s in fname_list])
dct['samoyed'] = sum(['samoyed'  in s for s in fname_list])
dct
{'pomeranian': 200, 'samoyed': 200}

HW 0327 (2)

1. 아래와 같은 맵핑을 고려하자.

문자 숫자
a 1
b 0

이를 딕셔너리로 표현하면 아래와 같다.

dct = {'a':0, 'b':1} 

위 규칙에 따라서 아래의 리스트의 원소를 문자로 각각 변환하라.

lst = [1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1]
# 출력은 아래와 같아야 한다. 
['b', 'a', 'b', 'a', 'b', 'a', 'b', 'b', 'b', 'b', 'a', 'a', 'b', 'a', 'b']

(풀이)

[k for l in lst for k,v in dct.items() if v==l]
['b', 'a', 'b', 'a', 'b', 'a', 'b', 'b', 'b', 'b', 'a', 'a', 'b', 'a', 'b']

2. 아래와 같은 맵핑을 고려하자.

의미
1,2 겨울방학
3,4,5,6 1학기
7,8 여름방학
9,10,11,12 2학기

이러한 규칙에 맞게 아래의 리스트를 적절한 문자열로 변환하라.

month = [1,2,2,3,4,5,6,7,8,9,9,10,11,12] 
## 출력은 아래와 같아야 한다. 
['겨울방학', '겨울방학', '겨울방학', '1학기', '1학기', '1학기', '1학기', '여름방학', '여름방학', '2학기', '2학기', '2학기', '2학기', '2학기']

(풀이)

dct = {'겨울방학':[1,2], '1학기':[3,4,5,6], '여름방학':[7,8], '2학기':[9,10,11,12]} 
[k for m in month for k,v in dct.items() if m in v] 
['겨울방학',
 '겨울방학',
 '겨울방학',
 '1학기',
 '1학기',
 '1학기',
 '1학기',
 '여름방학',
 '여름방학',
 '2학기',
 '2학기',
 '2학기',
 '2학기',
 '2학기']

합성변환 3-5.

아래와 같은 맵핑을 고려하자.

(규칙1)

문자 숫자
바나나 0
사과 1
오토바이 2
자동차 3
자전거 4

(규칙2)

아이템 카테고리
바나나 과일
사과 과일
오토바이 탈것
자동차 탈것
자전거 탈것

각각의 규칙을 나타내는 딕셔너리는 아래와 같이 선언되어있다고 하자.

dct1 = {'바나나':0, '사과':1, '오토바이':2, '자동차':3, '자전거':4} 
dct2 = {'과일':['바나나','사과'], '탈것':['오토바이','자동차','자전거']} 

3. 규칙1를 이용하여 아래와 같은 리스트를 변환하는 함수를 구현하고 그 함수를 f라 선언하라.

# 입력 
[0,1,0,1,4]

# 출력 
['바나나', '사과', '바나나', '사과', '자전거']

(사용예시)

f([0,1,0,1,4])
['바나나', '사과', '바나나', '사과', '자전거']

(풀이)

def f(lst):
    return [k for l in lst for k,v in dct1.items() if v == l]    
f([0,1,0,1,4])
['바나나', '사과', '바나나', '사과', '자전거']

4. 규칙2를 이용하여 아래와 같이 리스트를 변환하는 함수를 구현하고 그 함수를 g라고 선언하라.

# 입력 
['바나나','바나나','바나나','자동차']

# 출력 
['과일','과일','과일','탈것']

(사용예시)

g(['바나나','바나나','바나나','자동차'])
['과일', '과일', '과일', '탈것']

(풀이)

dct2
{'과일': ['바나나', '사과'], '탈것': ['오토바이', '자동차', '자전거']}
def g(lst):
    return [k for l in lst for k,v in dct2.items() if l in v] 
g(['바나나','바나나','바나나','자동차'])
['과일', '과일', '과일', '탈것']

5. 규칙1-2를 이용하여 아래와 같은 숫자로 이루어진 입력을 ‘과일’, ‘탈것’ 중 하나로 바꾸는 코드를 구현하라.

# 입력 
[0,1,0,1,3,4,2,2,3,4,1,0]

# 출력 
['과일', '과일', '과일', '과일', '탈것', '탈것', '탈것', '탈것', '탈것', '탈것', '과일', '과일']

hint \(g(f(x))\) 를 이용하라.

(풀이)

g(f([0,1,0,1,3,4,2,2,3,4,1,0]))
['과일', '과일', '과일', '과일', '탈것', '탈것', '탈것', '탈것', '탈것', '탈것', '과일', '과일']