언어/PYTHON

튜플, 리스트

빨대도둑 2022. 10. 13. 13:41

파이썬에는 튜플과 리스트라는 시퀀스 구조가 있다. 이 구조는 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() 등과 같은 함수가 없고 튜플을 생성한 후에는 수정할 수 없어서 함수의 수가 매우 적다.

「튜플을 사용하는 이유」

  1. 튜플은 더 적은 공간을 사용한다
  2. 실수로 튜플의 항목이 손상될 염려가 없다
  3. 튜플은 딕셔너리 키로 사용할 수 있다
  4. 네임드튜플은 객체의 단순한 대안이 될 수 있다. 

> 하지만 일반적으로 리스트와 딕셔너리를 더 많이 사용한다. 

 

'언어 > PYTHON' 카테고리의 다른 글

함수, 예외  (0) 2022.10.17
딕셔너리와 셋  (0) 2022.10.14
텍스트 문자열  (0) 2022.10.12
조건, 반복  (0) 2022.10.12
데이터 타입  (0) 2022.10.10