파이썬에는 튜플과 리스트라는 시퀀스 구조가 있다. 이 구조는 0 또는 그 이상의 항목을 포함한다. 문자열과 달리 다른 타입이 될 수 있다. 즉 각 요소는 어떤 객체도 될 수 있다. 이것은 프로그래머가 원하는 대로 깊고 복잡한 구조를 만들 수 있게 해 준다.
튜플은 불변하다. 튜풀에 항목을 할당하고 나면 바꿀 수 없다.
리스트는 가변 하다. 항목을 할당하고 나서 자유롭게 수정하거나 삭제할 수 없다.
「튜플」
tuple=()
->()
marx='iron',
->('iron',)
mrax=('iron',)
->('iron',)
mrax_tuple='iron', 'alpha','beta'
mrax_tuple
->('iron', 'alpha','beta')
「튜플 특징」
- 튜플을 괄호 안에 한 요소만 있고, 콤마를 생략하면 튜플이 아니라 문자열이 된다. 또한 요소가 두 개 이상이면 마지막에는 콤마를 붙이지 않는다.
- 파이썬은 튜플을 출력할 때 (괄호)를 포함한다. 튜플을 정의할 때는 (괄호)가 필요없다. 뒤에 콤마가 붙는다는 것은 튜플을 정의한다는 뜻이다. 그러나 값들을 괄호로 묶어서 튜플을 정의하면 이것은 튜플인지 구분하기 더 쉽다.
- 하지만 콤마를 다른 용도로 사용하려면 괄호가 필요하다.(함수, 메스드의 인수).
- 튜플로 한번에 여러 번수를 할당할 수 있다.
「tuple( )」: 다른 객체를 튜플로 만들어줌
city=['seoul','new york','los angeles']
tuple(city)
->('seoul','new york','los angeles')
「+」: 결합
('seoul')+('new york','los angeles')
->('seoul','new york','los angeles')
「*」: 복사
('seoul')*3
->('seoul','seoul','seoul')
「비교하기」
a=(7,2)
b=(7,2,6)
a==b
->False
a<=b
->True
a<b
True
「for, in」: 순회하기
fish=('cuttlefish','tuna','halibut')
for word in fish:
print(word)
->
cuttlefish
tuna
halibut
※ 튜플은 문자열 처럼 불변 객체이므로 기존 튜플을 변경할 수 없다. 문자열과 같이 튜플을 결합하여 새 튜플을 만들 수 있다.
tree=('maple','pine','cherry blossoms')
flower=('rose',)
tree+flower
->('maple', 'pine', 'cherry blossoms', 'rose')
「리스트」
- 리스트는 데이터를 순차적으로 파악하는데 유용하다.
- 내용의 순서를 바꿀 수 있다.
- 문자열과 달리 리스트는 변경이 가능하다.
- 리스트는 현재의 위치에서 새로운 요소를 추가, 삭제하거나 기존 요소를 덮어쓸 수 있다.
- 리스트에는 동일한 값이 여러번 나올 수 있다.
「 」:생성
empty_list=[]
number=['one','two','three']
birds=['emu','chicken','ostrich']
worldcup_year=['2002','2006','2014']
「list( ) 」:생성, 변환하기
new_list=list()
new_list
->[]
> list()함수는 다른 데이터 타입(튜플, 문자열, 셋, 딕셔너리)을 리스트로 변환한다.
list('lamborghini')
->['l', 'a', 'm', 'b', 'o', 'r', 'g', 'h', 'i', 'n', 'i']
tuple_car=('lamborghini','benz','ferrari')
list(tuple_car)
->['lamborghini', 'benz', 'ferrari']
「split( ) 」:문자열 분할로 생성하기
car_model='ferrai/purosangue/suv'
car_model.split('/')
->['ferrai', 'purosangue', 'suv']
「offset 」: 항목 얻기
car=['benz','bmw','audi']
car[0]
->'benz'
car[-1]
->'audi'
> 문자열과 마찬가지로 음수 인덱스는 끝에서부터 거꾸로 값을 출력한다.
> 리스트 오프셋은 값을 할당한 위치에 만 게 입력되어야 한다. 오프셋의 위치가 리스트의 범위를 벗어나면 오류가 발생한다.
「슬라이스」
car=['benz','bmw','audi','porsche','ferrari']
car[0:2]
->['benz', 'bmw']
car[::2]
->['benz', 'audi', 'ferrari']
car[::-2]
->['ferrari', 'audi', 'benz']
> 리스트 슬라이스는 문자열 슬라이스와 같이 잘못된 인덱스를 지정할 수 있지만 예외는 발생하지 않는다. 유효 범위의 인덱스를 반환하거나 아무것도 반환하지 않는다.
「append( )」:리스트 끝에 항목 추가하기
car=['benz','bmw','audi','porsche','ferrari']
car.append('mini')
car
->['benz', 'bmw', 'audi', 'porsche', 'ferrari', 'mini']
「오프셋과 insert( )」
> append()메서드는 리스트의 끝에 항목만 추가한다. 그러나 insert( ) 메서드는 원하는 위치에 항목을 추가할 수 있다. 오프셋 0은 시작점에 항목을 삽입하고, 리스트의 끝을 넘는 오프셋은 append( )처럼 끝에 항목을 추가한다.
['benz', 'bmw', 'audi', 'porsche', 'ferrari', 'mini']
car=['benz','bmw','audi','porsche','ferrari']
car.insert(2,'kia')
car
->['benz', 'bmw', 'kia', 'audi', 'porsche', 'ferrari']
car.insert(10,'toyota')
car
->['benz', 'bmw', 'kia', 'audi', 'porsche', 'ferrari', 'toyota']
「복사하기」
['car']*3
->['car', 'car', 'car']
「extend( ),+」: 병합하기
car=['benz', 'bmw', 'kia', 'audi', 'porsche', 'ferrari', 'toyota']
others=['ford','mustang']
car.extend(others)
car
->['benz', 'bmw', 'kia', 'audi', 'porsche', 'ferrari', 'toyota', 'ford', 'mustang']
plus=['GM','GMC','HUMMER']
car+=plus
car
->['benz', 'bmw', 'kia', 'audi', 'porsche', 'ferrari', 'toyota', 'ford', 'mustang', 'GM', 'GMC', 'HUMMER']
> append()를 사용하면 항목을 병합하지 않고 others가 하나의 리스트로 추가된다.
「offset」:항목 바꾸기
car=['benz', 'bmw', 'porsche', 'ferrari']
car[3]='lamborghini'
car
->['benz', 'bmw', 'porsche', 'lamborghini']
- offset은 리스트에서 유효한 위치여아 한다.
- 문자열은 불변 객체고 리스트는 가변 객체이기 때문에 위와 같은 방식으로 문자열을 변경할 수 없다.
- 리스트 항목수와 항목 내용을 바꿀 수 있다.
「슬라이스」:항목 바꾸기
number=[1,2,3,4,5]
number[1:3]=[7,8,9]
number
->[1, 7, 8, 9, 4, 5]
number[1:3]=[]
number
->[1, 9, 4, 5]
number[1:3]='why?'
number
->[1, 'w', 'h', 'y', '?', 5]
- 슬라이스를 사용하여 하위 리스트를 얻는다
- 슬라이스는 하위 리스트에 값을 할당할 수 있다
- 리스트에 할당되는 오른쪽 값으 수는 왼쪽 슬라이스 항목 수와 달라도 된다
- 오른쪽 값은 리스트가 아니어도 된다. 순회 가능한 타입 값을 리스트 항목에 할당할 수 있다.
「del( ), remove( )」: 항목 삭제하기
car=['benz', 'bmw', 'porsche', 'ferrari']
car[-1]
'ferrari'
del car[-1]
car
->['benz', 'bmw', 'porsche']
car.remove('bmw')
car
->['benz', 'porsche']
- del은 리스트 메서드가 아니라 파이썬 구문이다.
- del은 객체로부터 이름을 분리하고 이 이름이 객체의 마지막 참조라면 객체의 메모리를 비운다
- 리스트에서 삭제할 항목의 위치를 모른다면 값과 remove( )로 그 항목을 삭제할 수 있다.
「pop( )」: offset으로 항목 얻은 후 삭제
car=['benz', 'bmw', 'porsche', 'ferrari']
car.pop()
->'ferrari'
car
->['benz', 'bmw', 'porsche']
car.pop(1)
->'bmw'
car
->['benz', 'porsche']
> pop( )은 리스트에서 항목을 가져오는 동시에 그 항목을 삭제한다. pop( )과 그 인수로 offset을 호출했다면, 해당 offset의 항목이 반환된다. 인수가 없다면 기본 값은 -1이다. pop(0)은 리스트의 머리(시작)를 반환한다. 그리고 pop()이나 pop(-1)은 리스트의 꼬리(끝)를 반환한다.
※append( )로 새로운 항목을 끝에 추가한 뒤 pop()으로 다시 마지막 항목을 제거했다면 후입선출(LIFO) 자료구조인 스택을 구한한 것이다. 그리고 pop(0)을 사용했다면 선입선출(FIFO) 자료구조인 큐를 구현한 것이다. 이들은 수집한 데이터에서 가장 오래된 것을 사용하거나(FIFO) , 최근 것을 먼저 사용할 때 유용하다(LIFO).
「clear( )」:모든 값 삭제하기
car=['benz', 'bmw', 'porsche', 'ferrari']
car.clear()
car
->[]
「index( )」:값으로 offset찾기
car=['benz', 'bmw', 'porsche', 'ferrari','benz']
car.index('benz')
->0
- 리스트 항목 값의 offset을 알고 싶다면 index()를 사용 하면 된다.
- 리스트에 같은 값이 2개 이상이면 첫 번째 offset만 반환된다.
「in」:존재여부 확인하기
car=['benz', 'bmw', 'porsche', 'ferrari','jeep']
'jeep' in car
->True
'ford' in car
->False
- 리스트에 어떤 값의 존재를 확인하기 위해 in을 사용한다.
- 리스트에는 같은 값이 여러 개 존재할 수 있다. 리스트에 값이 적어도 1개 이상 존재하면 in은 true를 반환한다.
「count( )」:값 세기
> 리스트에 특정 항목이 얼마나 있는지 세기 위해서 count( )를 사용
car=['benz', 'bmw', 'porsche', 'ferrari','jeep']
car.count('benz')
->1
car.count('ford')
->0
「join( )」:문자열로 변환하기
car=['benz', 'bmw', 'porsche', 'ferrari','jeep']
', '.join(car)
->'benz, bmw, porsche, ferrari, jeep'
car=['benz', 'bmw', 'porsche', 'ferrari','jeep']
seperator='/'
joined=seperator.join(car)
joined
->'benz/bmw/porsche/ferrari/jeep'
seperated=joined.split(seperator)
seperated
->['benz', 'bmw', 'porsche', 'ferrari', 'jeep']
seperated==car
->True
> join()의 인수는 문자열 혹은 순회 가능한 문자열의 시퀀스이다. 그 결과로 반환되는 값은 문자열이다. join()이 리스트 메서드였다면, 튜플과 문자열 같은 다른 순회 가능한 객체와 함께 사용하지 못할 것이다. 어떤 순회 가능한 타입을 처리하기 위해 각 타입을 실제로 병합할 수 있도록 특별한 코드가 필요했다. join()과 split()은 반대기능이다.
「sort( ), sorted( )」: 정렬하기
car=['benz', 'bmw', 'porsche', 'ferrari','jeep']
sorted_car=sorted(car)
car
->['benz', 'bmw', 'porsche', 'ferrari', 'jeep']
car=['benz', 'porsche', 'ferrari','jeep','bmw']
sorted_car=sorted(car)
sorted_car
->['benz', 'bmw', 'ferrari', 'jeep', 'porsche']
car
->['benz', 'porsche', 'ferrari', 'jeep', 'bmw']
car.sort()
car
->['benz', 'bmw', 'ferrari', 'jeep', 'porsche']
number=[1,2,3.14,2.1]
number.sort()
number
->[1, 2, 2.1, 3.14]
number.sort(reverse=True)
number
->[3.14, 2.1, 2, 1]
- sort()는 리스트 자체를 내부적으로 정렬한다.
- sorted()는 리스트의 정렬된 복사본을 반환한다.
- 리스트 요소들이 모두 같은 타입이면 sort()는 제대로 작동한다. 때때로 정수수와 부동소수점 숫자 같이 혼합된 타입도 정렬할 수 있다. → 파이썬이 자동으로 타입을 변환해서 항목을 정렬하기 때문이다.
- 기본 정렬 방식은 오름차순이다. 내림 차순으로 정렬하고 싶으면, 인수에 reverse=True를 추가하면 된다.
「len( )」: 항목 개수 얻기
car=['benz', 'bmw', 'porsche', 'ferrari','jeep']
len(car)
->5
「=」: 할당하기
a=[1,2,3,4,5]
b=a
b
[1, 2, 3, 4, 5]
a[0]='number'
a
->['number', 2, 3, 4, 5]
b
->['number', 2, 3, 4, 5]
b[1]='first title'
b
->['number', 'first title', 3, 4, 5]
a
->['number', 'first title', 3, 4, 5]
- 한 리스트를 변수 두 곳에 할당했을 때 한 리스트를 변경하면 다른 리스트도 같이 변경된다.
- b는 단지 같은 리스트 객체 a를 참조한다. 따라서 a 또는 b리스트 내용을 변경하면 두 변수 모두에 반영된다.
「copy( ), list( ), 슬라이스」: 복사하기
a=[1,2,3,4,5]
b=a.copy()
c=list(a)
d=a[:]
a[0]='long way from home'
a
->['long way from home', 2, 3, 4, 5]
b
->[1, 2, 3, 4, 5]
c
->[1, 2, 3, 4, 5]
d
->[1, 2, 3, 4, 5]
- copy() 메서드
- list() 변환함수
- 슬라이스[:]
- 위 코드는 원본 리스트 a가 있는데 copy()로 리스트 b를 만들고, list() 변환 함수로 리스트 c를 만든다. 그리고 a를 슬라이스 해서 리스트 d를 만든다.
- b, c, d는 a의 복사본이다. 이들은 자신만의 값을 가진 새로운 객체이다. 그래서 원본 리스트 객체[1,2,3]를 참조하는 아무런 참조가 없다. 복사본 b, c, d를 바꾸더라고 원본 a에는 아무런 영향을 주지 않는다.
「deepcopy」: 깊은 복사
a=[1,2,3,[5,6]]
b=a.copy()
c=list(a)
d=a[:]
a
->[1, 2, 3, [5, 6]]
b
->[1, 2, 3, [5, 6]]
c
->[1, 2, 3, [5, 6]]
d
->[1, 2, 3, [5, 6]]
a[3][1]=99
a
->[1, 2, 3, [5, 99]]
b
->[1, 2, 3, [5, 99]]
c
[1, 2, 3, [5, 99]]
->d
[1, 2, 3, [5, 99]]
a[3][1]=99
a
->[1, 2, 3, [5, 99]]
b
->[1, 2, 3, [5, 99]]
c
->[1, 2, 3, [5, 99]]
d
->[1, 2, 3, [5, 99]]
import copy
a=[1,2,3,4,[88,99]]
b=copy.deepcopy(a)
a
->[1, 2, 3, 4, [88, 99]]
b
->[1, 2, 3, 4, [88, 99]]
a[4][1]=100
a
->[1, 2, 3, 4, [88, 100]]
b
->[1, 2, 3, 4, [88, 99]]
- 리스트 값이 모두 불변이면 copy() 메서드는 제대로 작동한다. 리스트, 튜플, 딕셔너리와 같은 가변 객체는 참조일 뿐이다. 원본과 사본의 변경사항을 모두 반영한다.
- deepcopy()는 하위에 중첩된 리스트, 딕셔너리, 기타 다른 객체를 모두 복사한다.
「리스트 비교」
x=[11,22,33,44,55]
y=[11,22,33]
x==y
False
x<=y
False
x>=y
True
x>y
True
z=[22,33]
x<z
True
- ==,<등과 같은 비교 연산자와 리스트를 직접 비교할 수 있다. 비교 연산자는 두 리스트의 같은 위치의 오프셋 항목을 비교한다. 리스트 x가 y보다 길이가 길고 모든 요소가 같으면 x는 y보다 크다.
「for, in」: 순회하기
for 반복자 in 반복할 수 있는 것
코드
array=[273,556,112,554]
for element in array:
print(element)
->
273
556
112
554
- for 반복문은 리스트에 있는 요소 하나하나가 element라는 변수에 들어가며, 차례대로 반복하게 됩니다.
- for 반복문은 문자열을 함께 사용할 수 도 있습니다.
for char in '서울아크로포레스트':
print("-",char)
->
- 서
- 울
- 아
- 크
- 로
- 포
- 레
- 스
- 트
「튜플 vs 리스트」
> 리스트 대신 튜플을 사용할 수 있다. 하지만 튜플은 리스트의 append(), insert() 등과 같은 함수가 없고 튜플을 생성한 후에는 수정할 수 없어서 함수의 수가 매우 적다.
「튜플을 사용하는 이유」
- 튜플은 더 적은 공간을 사용한다
- 실수로 튜플의 항목이 손상될 염려가 없다
- 튜플은 딕셔너리 키로 사용할 수 있다
- 네임드튜플은 객체의 단순한 대안이 될 수 있다.
> 하지만 일반적으로 리스트와 딕셔너리를 더 많이 사용한다.