강의영상

- (1/2) 튜플, 슬기롭게 튜플 사용하기 (1)

- (2/2) 슬기롭게 튜플 사용하기 (2)

튜플

리스트 vs 튜플

- 컨테이너형타입이라는 점, 그리고 연산 및 인덱싱을 하는 방법은 리스트와 같음

  • 차이점1: [] 대신에 ()를 사용한다.
  • 차이점2: 불변형이다. (원소의 값을 바꿀 수 없음)
  • 차이점3: 하나의 원소를 선언할 때는 (1,)와 같이 해야 한다.
  • 차이점4: 의미가 명확할때는 튜플의 ()를 생략가능하다.

- 컨테이너형이라는 것이 무슨의미?

a=(4,6,'pencil', 3.2+4.6j, [3,4]) 
type(a[2])
str
type(a[3])
complex

- 불변형이라는 것은 무슨의미?

a[2] = 'Pencil'
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Input In [13], in <cell line: 1>()
----> 1 a[2] = 'Pencil'

TypeError: 'tuple' object does not support item assignment

참고로 a를 튜플이 아니라 리스트로 선언하면 값이 잘 바뀐다.

a=[4,6,'pencil', 3.2+4.6j, [3,4]]
a[2]
'pencil'
a[2]='Pencil'
a
[4, 6, 'Pencil', (3.2+4.6j), [3, 4]]

- 하나의 원소로 이루어진 튜플을 만들때는 쉼표를 붙여야 함.

[1]+[2,3,4]
[1, 2, 3, 4]
(1,)+(2,3,4)
(1, 2, 3, 4)

- 마지막차이점! 의미가 명확할때 튜플의 괄호는 생략가능하다. (이게 중요합니다)

a=1,2
a
(1, 2)

의미가 명확할때 생략해야함

1,2 + 3,4,5 
(1, 5, 4, 5)
(1,2) + (3,4,5) 
(1, 2, 3, 4, 5)

선언

- 소괄호를 이용

a=(1,2,3)
a
(1, 2, 3)
type(a)
tuple

- 생략가능하다는 점이 포인트

a=1,2,3
a
(1, 2, 3)
type(a)
tuple

- 원소가 하나인 튜플을 만들고 싶다면?

a=(1,)
a
(1,)

연산

- 리스트와 동일

(1,2)+(3,4,5)
(1, 2, 3, 4, 5)
(1,2)*2
(1, 2, 1, 2)

인덱싱

- 리스트와 동일

a=(1,2,3,-4,-5)
a
(1, 2, 3, -4, -5)
a[-1]
-5
a[-3:]
(3, -4, -5)

튜플고급

튜플을 왜 불변형으로 만들었을까?

  • 책의설명: 실수로 값을 변경할 수 있도록 방지할 수 있다.
  • shallow copy / deep copy 를 막을 수 있는 무기

튜플을 슬기롭게 사용하는 방법 ($\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 i in lst: 
    print(i)
['guebin', 202112345, 'M']
['iu', 202254321, 'F']
['hodong', 202011223, 'M']
for name,studentid,sex in lst: 
    print(name)
guebin
iu
hodong
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                                Traceback (most recent call last)
Input In [88], in <cell line: 1>()
----> 1 for name,_  in lst: 
      2     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]
  Input In [103]
    *[1,2,3]
    ^
SyntaxError: can't use starred expression here
print([1,2,3])
[1, 2, 3]
print(*[1,2,3]) ## 이런 느낌이란 말이지..
1 2 3

- 예제: 함수의 입력으로 *args를 넣을때

[예비학습] 함수 벼락치기

def myadd(a,b): 
    return a+b 
myadd(3,-3)
0

벼락치기 끝

예제시작: 두점 사이의 거리를 구하는 함수를 만들어 보자.

점 $p=(p_x,p_y)$와 $q=(q_x,q_y)$의 거리는 $\sqrt{(p_x-q_x)^2+(p_y-q_y)^2}$이다. 이것을 계산하는 프로그램을 만들자.

import numpy as np 
def dist(px,py,qx,qy): 
    return np.sqrt((px-qx)**2 + (py-qy)**2)
p=(0,3)
q=(4,0)
dist(p,q)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Input In [119], in <cell line: 3>()
      1 p=(0,3)
      2 q=(4,0)
----> 3 dist(p,q)

TypeError: dist() missing 2 required positional arguments: 'qx' and 'qy'

(방법1)

px,py = (0,3)
qx,qy = (4,0) 
dist(px,py,qx,qy)
5.0

(방법2)

def dist2(p,q):
    px,py = p 
    qx,qy = q 
    return np.sqrt((px-qx)**2 + (py-qy)**2)

### 이건 나쁜 생각이에요.. 
# def dist2(p,q):
#     px=p[0]
#     py=p[1]
#     qx=q[0]
#     qy=q[1]
#     return np.sqrt((px-qx)**2 + (py-qy)**2)
p=(0,3)
q=(4,0)
dist2(p,q)
5.0

(방법3)

dist(*p,*q) # 입력을 *(px,py), *(qx,qy) 형태로 넣기도하고.. 
5.0
dist(px,py,qx,qy) # 입력을 px,py,qx,qy 형태로 넣기도하고.. 
5.0

(숙제) 원소로 자기학번을 포함하는 튜플을 만들어서 제출 (길이가 1인 튜플을 만들어서 제출)