Lecture 5. TUPLES, LISTS, ALIASING, MUTABILITY, CLONING
이 글은 Mit Open Courseware(OCW)에서 공개한 교육자료이며 OCW의 라이센스정책을 따릅니다.
License : Common Creative License : BY-NC-SA (저작자표시-비영리-동일조건변경허락)
출처 : https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-0001-introduction-to-computer-science-and-programming-in-python-fall-2016/lecture-slides-code/MIT6_0001F16_Lec5.pdf
1. TUPLES
1) Tuple의 정의
- 여러 data type의 element를 저장할 수 있는 ordered sequence
- 값을 변경할 수 없음 (immutable)
- 괄호() 로 표시
te = ( ) # empty tuple (#은 한줄 주석)
t = (2, "mit", 3)
t[0] # 2 출력
(2 , "mit" , 3) + (5, 6) # ( 2, "mit", 3, 5, 6 ) 출력
t [1:2] # slice tuple. ("mit", ) 출력. , 는 튜플이 하나의 원소만 존재함을 의미
t [1:3] # slice tuple. ("mit", 3 ) 출력.
len(t) # 튜플의 길이. 3
t[1] = 4 # 변경불가. 오류
t1 = (1) # 튜플이 아님. type(t1) 의 결과는 int
t2 = (1, ) # 원소 하나인 튜플
2) Tuple의 사용
- 두개 이상의 변수를 서로 바꿀때 사용
# ex 1 : 아래 처럼 할 경우 x의 값이 사라짐
x = y
y = x
# ex 2 : 일반적으로 아래처럼 임시변수를 사용하여 값을 치환
temp = x
x = y
y = temp
# ex3 : 튜플을 사용할 경우 아래처럼 간단하게 표기
(x , y) = (y , x)
- 함수에서 하나 이상의 값을 return 할 경우 사용
def quotient_and_remainder(x, y):
q = x // y
r = x % y
return (q, r)
(quot, rem) = quotient_and_remainder(4,5)
3) Manipulating Tuples
- Tuple을 통한 반복
def get_data(aTuple):
nums = ()
words = ()
for t in aTuple:
nums = nums + (t[0],) # 숫자 튜플 num에 aTuple의 숫자부분을 추가
if t[1] not in words: # 문자 튜플 words에 aTuple의 문자부분이 있는지 체크
words = words + (t[1],) # 없으면 문자 튜플 words에 aTuple의 문자부분 추가
min_n = min(nums)
max_n = max(nums)
unique_words = len(words)
return (min_n, max_n, unique_words)
test = ((1,"a"),(2, "b"),(1,"a"),(7,"b"))
(a, b, c) = get_data(test)
print("a:",a,"b:",b,"c:",c)
tswift = ((2014,"Katy"),
(2014, "Harry"),
(2012,"Jake"),
(2010,"Taylor"),
(2008,"Joe"))
(min_year, max_year, num_people) = get_data(tswift)
print("From", min_year, "to", max_year, \
"Taylor Swift wrote songs about", num_people, "people!")
2. LIST
1) List의 정의
- index로 접근가능한 ordered sequence
- list는 [ ] 으로 표시
- list는 일반적으로 동일한 data type만 저장하지만 다른 data type도 허용
- list의 원소는 변경가능
- list의 index는 0부터 len(L)-1까지
a_list = []
L = [2, 'a', 4, [1,2]]
len(L) # 4
L[0] # 2
L[2]+1 # 5
L[3] # [1,2],
L[4] # 오류
i = 2
L[i-1] # 'a'
2) List 의 element 변경
- tuple과 달리 list는 변경가능
- 아래의 예에서 L의 값의 변경은 동일한 객체에서 이루어진다. (String은 immutable이므로 변경할 경우 변경이 아닌 다른 객체가된다.)
L = [2, 1, 3]
L[1] = 5
print(L) # [2, 5, 3]
3) list를 통한 반복
total = 0
for i in L:
total += i
print total
4) list의 연산 - ADD
- L.append(element) 의 형태로 element 추가
L = [2,1,3]
L.append(5) # [2,1,3,5]
L.append([2,3]) # [2, 1, 3, 5, [2, 3]]
5) list의 연산 - concatenation(+) , extend
L1 = [2,1,3]
L2 = [4,5,6]
L3 = L1 + L2 # L3 : [2,1,3,4,5,6] . L1과 L2는 미변경
L1.extend([0,6]) # L1 이 [2,1,3,0,6] 으로 변경
6) list의 연산 - 삭제
- 특정 인덱스의 element의 삭제는 del(L[index])
- list의 마지막 element의 삭제는 L.pop()
- 특정 element의 삭제는 L.remove(element)
=> element가 list에 여러개가 존재할 경우 첫번째 만나는것만 삭제
=> list에 없을 경우 에러
L = [2,1,3,6,3,7,0]
L.remove(2) # L = [1,3,6,3,7,0]
L.remove(3) # L = [1,6,3,7,0]
del(L[1]) # L = [1,3,7,0]
L.pop() # 0을 return. L = [1,3,7]
L.remove(5) # 5가 list에 없으므로 error
7) list -> string, string -> list
- 문자열을 list로 바꾸기 : list(s)
- 문자열을 separator로 구분하여 분리. separator가 없을 경우 space : s.split(separator)
- list의 문자를 문자열로 바꾸기 : ''.join(L)
s = "I<3 cs"
list(s) # ['I','<','3',' ','c','s']
s.split('<') # ['I', '3 cs']
L = ['a','b','c']
''.join(L) # "abc"
'_'.join(L) # "a_b_c"
8) list의 다른 Operation
L = [9, 6, 0, 3]
sorted(L) # [0, 3, 6, 9] 을 return. L 자체는 변경되지 않는다
L.sort() # return값 없음. L이 [0, 3, 6, 9] 로 정렬되어 변경
L.reverse() # return값 없음. L이 [9, 6, 3, 0] 으로 순서가 바뀌어서 변경
다른 상세한 기능은 공식 홈페이지 참조
https://docs.python.org/3/tutorial/datastructures.html]
3. MUTATION, ALIASING, CLONING
1) List 의 특성
- List 를 나타내는 변수는 List 객체의 주소를 갖고있는 형태
- 다른 변수에 이전 변수를 할당하면 두 변수는 같은 List를 의미
- 이전 변수를 통해 List 의 값을 변경하면 다른 변수도 영향을 받음
a = 1
b = a
print(a) # 1
print(b) # 1
warm = ['red', 'yellow', 'orange']
hot = warm
hot.append('pink')
print(hot) # ['red', 'yellow', 'orange', 'pink']
print(warm} # ['red', 'yellow', 'orange', 'pink']
2) Cloning a list
- 기존 List를 복제해서 새로운 List를 만들기
cool = ['blue', 'green', 'grey']
chill = cool[:]
chill.append('black')
print(chill) # ['blue', 'green', 'grey', 'black']
print(cool) # ['blue', 'green', 'grey']
3) Sorting list
- sort()는 List 자체를 정렬하고 return 값이 없음
- sorted()는 List 자체는 변경이 없고 return값으로 정렬된 List
warm = ['red', 'yellow', 'orange']
sortedwarm = warm.sort()
print(warm) # ['orange', 'red', 'yellow']
print(sortedwarm) # None
cool = ['blue', 'green', 'black']
sortedcool = sorted(cool)
print(cool) # ['blue', 'green', 'black']
print(sortedCool) # ['black', 'blue', 'green']
4) List의 List
- List는 List를 원소로 가질 수 있다. (nested list)
warm = ['yellow', 'orange']
hot = ['red']
brightcolors = [warm]
print(brightcolors) # [['yellow', 'orange']]
brightcolors.append(hot) # hot라는 변수로 append를 했으므로 hot가 변경되면 brightcolor도 변경된다
print(brightcolors) # [['yellow', 'orange'], ['red']]
hot.append('pink')
print(hot) # ['red', 'pink']
print(brightcolors) # [['yellow', 'orange'], ['red', 'pink']]
5) Iteration에서의 List
- 반복문에서 List를 반복기준으로 사용할 경우 복제해서 사용한다
- 반복문 내에서 List를 조작하면 반복자체에 영향을 받기 때문에 복제가 필요하다
- 아래 예제에서 remove_dups(L1, L2) 수행 후의 L1의 값이 [2,3,4] 인 이유는 파이썬 내부에서 반복을 수행할때 counter를 통해 인덱스를 증가시키는데 L1과 L2 비교시 1이 중복이어서 L1에서 삭제되면 list 의 길이는 3으로 줄지만 인덱스는 1로 증가되므로 2를 건너뛰고 3으로 넘어가게 된다.
def remove_dups(L1, L2):
for e in L1: # L1을 iteration으로 사용
if e in L2:
L1.remove(e) # L1의 원소가 제거되면 iteration이 영향을 받음
def remove_dups_2(L1, L2):
L1_copy = L1[:] # L1을 colone해서 iteration으로 사용
for e in L1_copy:
if e in L2:
L1.remove(e) # L1의 원소가 제거되어도 iteration은 영향받지 않음
L1 = [1, 2, 3, 4]
L2 = [1, 2, 5, 6]
remove_dups(L1, L2)
print(L1) # [2, 3, 4]
L3 = [1, 2, 3, 4]
L4 = [1, 2, 5, 6]
remove_dups_2(L3, L4)
print(L3) # [3, 4]
댓글