03wk-2: 파이썬의 자료형 (5)

Author

최규빈

Published

March 22, 2023

튜플 고급내용

튜플을 왜 쓸까? (1)

- 책의 설명 (이 설명이 꼭 파이썬에 한정되는 것은 아님. 모든 언어에 존재하는 불변형 객체에 적용가능한 설명)

  • 실수방지
  • 빠르다, 다중작업에 유리하다, 여러사람과 작업하기에 유리하다, 깊은복사/얕은복사시 원하지않는 오류(side effect이라고 함)를 방지할 수 있다, 메모리관리에도 유리함…
  • 느낌: 불변형은 기능제한이 있는데 가볍고 빠른, 가변형은 기능은 풍부하지만 약간 느리고 무거운 느낌임 (불변형:라면사리, 가변형:라면)

슬기로운 튜플사용 (\(\star\star\star\star\star\))

- 예제: 여러변수를 동시에 출력하고 싶을 경우 (다중출력?)

변수를 아래와 같이 선언하였다고 하자.

a=1
b=2
c=3

선언된 값을 확인하려면?

a
1
b
2
c
3

튜플을 이용하면?

a,b,c # 괄호하나 생략하는것이 이렇게 편하다..
(1, 2, 3)

- 예제: 다중할당1 (여러개의 변수를 동시에 선언하고 싶을 경우)

name, age, sex, height, weight = 'Tom', 20, 'M', 180, 70 
name, age, sex, height, weight
('Tom', 20, 'M', 180, 70)
height
180

- 예제: 다중할당2, 위도와 경도

coor = (37,127) # 서울 
coor
(37, 127)
lat, long = coor
lat 
37
long 
127

- 잠깐만: 다중할당은 꼭 튜플에서만 가능한가?

그건 아니다…

[x,y,z] = [1,2,3] 
x,y,z # 다중출력 
(1, 2, 3)
[x,y] = 'hi'
x,y 
('h', 'i')

튜플과 같이 사용하면 가독성이 극대화 (그래서 다중할당은 거의 튜플과 세트로 사용함)

x,y,z = 1,2,3
x,y,z # 다중출력 
(1, 2, 3)
x,y = 'hi'
x,y 
('h', 'i')

- 예제: 임시변수 사용없이 두 변수의 값을 교환

a=10
b=20
a,b = b,a 
a
20
b
10

- 예제: for문과 튜플

lst = [['guebin', 202112345, 'M'],
       ['iu',202254321, 'F'],
       ['hodong', 202011223, 'M']]
lst
[['guebin', 202112345, 'M'],
 ['iu', 202254321, 'F'],
 ['hodong', 202011223, '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)
ValueError: too many values to unpack (expected 2)
for name,*args  in lst: 
    print(name)
guebin
iu
hodong

- 예제: 튜플과 언패킹연산자 *

head, body, *tail = range(1,11) 
head, body, tail
(1, 2, [3, 4, 5, 6, 7, 8, 9, 10])
head1,head2, *body, tail1,tail2,tail3 = range(1,11) 
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)

(관찰)

그러고 보니까..

head1,head2, body, tail1,tail2,tail3  = (1, 2, [3,4,5,6,7], 8, 9, 10)
head1,head2, *body, tail1,tail2,tail3   = (1, 2, 3,4,5,6,7, 8, 9, 10)

이렇다는 거잖아?

*를 붙이면 1차원 자료구조가 풀린다..?

*[1,2,3]
SyntaxError: can't use starred expression here (<ipython-input-37-63179bdb9a80>, line 1)
print([1,2,3])
[1, 2, 3]
print(*[1,2,3]) ## 이런 느낌이란 말이지..
1 2 3

튜플을 왜 쓸까? (2)

- 책의 설명 (이 설명이 꼭 파이썬에 한정되는 것은 아님. 모든 언어에 존재하는 불변형 객체에 적용가능한 설명)

  • 실수방지
  • 빠르다, 다중작업에 유리하다, 여러사람과 작업하기에 유리하다, 깊은복사/얕은복사시 원하지않는 오류(side effect이라고 함)를 방지할 수 있다, 메모리관리에도 유리함…
  • 느낌: 불변형은 기능제한이 있는데 가볍고 빠른, 가변형은 기능은 풍부하지만 약간 느리고 무거운 느낌임 (불변형:라면사리, 가변형:라면)

- 내 설명: 소괄화 생략할 수 있어서 쓰는거야

  • 튜플의 장점은 소괄호의 생략에 있음 (이것은 파이썬과 줄리아만 가능)
  • 소괄호생략 + 언패킹 \(\Rightarrow\) 엄청난 가독성
  • 컴공과 사람들 의견: 튜플 + 언패킹 \(\Rightarrow\) 엄청난 가독성 \(\Rightarrow\) 충격 \(\Rightarrow\) “파이썬 편하더라고요..”
def mycal(a,b):
    return a+b, a-b, a*b, a/b  #여러개의 값을 리턴하는듯 보임. -> 사실은 길이가 4인 튜플 1개를 리턴
mycal(2,3)
(5, -1, 6, 0.6666666666666666)
_, _, mulrslt, _ = mycal(2,3) # 병렬할당 
mulrslt
6

- 의문: 왜 튜플만 괄호를 생략할 수 있지?

답이 없는 문제인데 답을 해보겠습니다.

  • 튜플을 먼저 만들고, 괄호를 생략하는 문법을 추가한것은 아닐것임
  • 원래 괄호없이 컴마만 대충찍어서 선언가능한 아주간단한 타입의 벡터형을 만들고 싶었을 것임.
  • 왜? 괄호없는 벡터를 만들고, 언패킹을 사용하면 여러가지 구문들이 엄청나게 간단해짐.
  • 컴마컴마로 선언하는 벡터는 한 두번 쓰고 버리는 경우가 많으며 대부분 이름도 필요없음 \(\to\) 원소에 접근해서 sorting하여 순서를 바꾸고 싶다던가 원소를 추가할 이유가 없음 \(\to\) 비싼 가변형으로 만들 이유가 없다는 것..
  • 우리가 필요한 것: 데이터가 벡터의 형태로 모여있기만 하면 된다!

HW: 03-22 (2)

1. 길이가 1인 튜플을 만들어 자신의 학번을 저장하라. 길이가 1인 튜플을 만들어 자신의 영문이름을 저장하라. 두 튜플을 + 연산자로 합쳐아래와 같은 출력결과를 얻어라. 최종 결과는 예를들면 아래와 같아야 한다.

('2021-43052', 'GuebinChoi')
('2021-43052', 'GuebinChoi')

(풀이)

a='2021-43052', 
b='GuebinChoi',
a+b
('2021-43052', 'GuebinChoi')

2-5. 아래는 파이썬프로그래밍 수강생들의 학번, 이름, 출석점수, 과제점수, 중간고사점수, 기말고사점수를 저장한 중첩리스트이다.

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

2. 파이썬프로그래밍 수강생의 수는 모두 몇명인가?

(풀이)

len(lst)
8

3. 전북대학교 지침에 따라 출석점수가 7보다 작은 학생은 (즉 출석점수 < 7 일 경우) F학점을 부여하게 되어있다. 이 기준에 따르면 F를 받는 학생은 모두 몇명인가?

(풀이)

sum([att<7 for _,_, att, *rest in lst])
2

4. 파이썬프로그래밍 수업의 경우 출석+레포트 < 21 일 경우 F학점을 부여한다고 한다. 이 기준에 따르면 F를 받는 학생은 모두 몇명인가?

(풀이)

sum([att+rep < 21 for _,_, att,rep, *rest in lst])
2

5. 리스트의 정렬순서를 [학번, 이름, …, 기말고사점수] 가 아니라 [이름, 학번, … , 기말고사점수] 와 같이 되도록 변경하는 코드를 작성하라.

(출력예시)

[[name,studentid,*rest] for studentid, name, *rest in lst]
[['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]]

6. 아래의 코드를 관찰하라.

'2023-03-22'.split('-')
['2023', '03', '22']

이 코드를 바탕으로 split의 기능을 유추하라. (ChatGPT 활용해도 무방함)

(풀이)

생략..

7. 6의 실행결과를 되돌리는 코드를 작성하라. 즉

['2023', '03', '22']
['2023', '03', '22']

와 같은 리스트를 아래의 string으로 바꾸는 코드를 작성하라.

'2023-03-22'
'2023-03-22'

hint: join을 이용할 것

(풀이)

'-'.join(['2023', '03', '22'])
'2023-03-22'

다음은 인터넷에서 긁어온 어떠한 텍스트이다.

text = "국내뿐 아니라 해외 인기도 심상치 않다. 2023년 1월 18일 'Ditto'가 빌보드 핫 100에 96위로 진입했다. 이는 K-pop 역사상 데뷔후 최단 빌보드 Hot 100 차트 입성 기록이다. 다른 뮤지션들이 보통 데뷔 후 수년간 쌓아온 팬덤을 기반으로 빌보드에 입성한데 비해, 뉴진스의 기록은 이례적인 것으로 평가받고 있다. 또한 'OMG'가 빌보드 핫 100에 91위로 진입한 동시에 'Ditto'는 85위로 순위가 상승, 핫 100 주간차트에 두 곡을 올려놓았다. K-Pop 역사상 이 차트에 두 곡 이상을 진입시킨 아티스트는 방탄소년단과 블랙핑크가 유일하다. 'Ditto'는 1월 셋째주 기준, 빌보드뿐만 아니라 영국 오피셜 싱글 차트 '톱 100'에 2주 연속 진입하기도 했다."

8. text는 총 몇개의 문장으로 이루어져 있는가?

hint: 이 텍스트의 문장은 모두 .로 끝난다.

(풀이)

lst = text.split('. ')
lst 
['국내뿐 아니라 해외 인기도 심상치 않다',
 "2023년 1월 18일 'Ditto'가 빌보드 핫 100에 96위로 진입했다",
 '이는 K-pop 역사상 데뷔후 최단 빌보드 Hot 100 차트 입성 기록이다',
 '다른 뮤지션들이 보통 데뷔 후 수년간 쌓아온 팬덤을 기반으로 빌보드에 입성한데 비해, 뉴진스의 기록은 이례적인 것으로 평가받고 있다',
 "또한 'OMG'가 빌보드 핫 100에 91위로 진입한 동시에 'Ditto'는 85위로 순위가 상승, 핫 100 주간차트에 두 곡을 올려놓았다",
 'K-Pop 역사상 이 차트에 두 곡 이상을 진입시킨 아티스트는 방탄소년단과 블랙핑크가 유일하다',
 "'Ditto'는 1월 셋째주 기준, 빌보드뿐만 아니라 영국 오피셜 싱글 차트 '톱 100'에 2주 연속 진입하기도 했다."]
len(lst)
7

9. 각 문장은 몇개의 단어로 이루어져 있는가?

hint: 각 단어는 공백으로 구분된다.

(풀이)

[len(s.split(' ')) for s in lst]
[6, 9, 11, 18, 18, 12, 16]
sum([len(s.split(' ')) for s in lst])
90

10. 100이라는 단어가 포함된 문장은 모두 몇 개 인가?

hint: 아래의 코드를 관찰

'a' in 'abcd'
True

(풀이)

['100' in s for s in lst]
[False, True, True, False, True, False, True]
sum(['100' in s for s in lst])
4