파이썬

리스트 ( 컬렉션 타입 )

96__혀누 2024. 3. 13. 16:47

 

* 컬렉션타입?

 

여러 데이터들을 하나의 집합으로 구성하는 데이터 타입을 말하며, 기본적으로 [ 리스트, 튜플, 세트, 딕셔너리 등 ]이 있다.

 


리스트

여러 데이터들 ( 정수형, 문자형, 실수형 등 )을 하나의 변수에 저장할 수 있으며, 변환이 가능한 자료구조이다.
리스트를 만들 때는 대괄호([])로 감싸 주고 각 요솟값은 쉼표(,)로 구분해 준다.

리스트의 구조 : 

변수명 = [ 데이터1, 데이터2, 데이터3, ... ]
예시 )
li1 = [1, 3, 5, 7, 9]
print(li1)
print(type(li1)) 

>>>
[1, 3, 5, 7, 9] 
<class 'list'>  # list 타입으로 구분된다.
-----------------------------------------------------
# 정수형 말고도 다른 형태의 데이터 또는 여러 종류의 데이터를 하나의 리스트에 포함할 수 있다.
li3 = ['김사과', '반하나', '오렌지', '이메론']
print(li3)

>>> ['김사과', '반하나', '오렌지', '이메론']
-----------------------------------------------------
li4 = [1, 50.5, '김사과', True]
print(li4)

>>> [1, 50.5, '김사과', True]
-----------------------------------------------------
# 리스트가 저장된 변수의 데이터 타입은 list 이나,
각각의 데이터의 인덱스로 확인했을 경우엔, 각각의 데이터에 맞는 타입으로 확인할 수 있다.

li4 = [1, 50.5, '김사과', True]
print(li4)
print(type(li4[0]))

print(type(li4[0]))
print(type(li4[1]))
print(type(li4[2]))
print(type(li4[3]))

>>>
[1, 50.5, '김사과', True]
<class 'list'>

<class 'int'>
<class 'float'>
<class 'str'>
<class 'bool'>

 

인덱싱과 슬라이싱

 

리스트의 각각의 항목은 위치( 인덱스 )를 가지고 있으며, 슬라이싱이 가능하다.

li1 = [1, 3, 5, 7, 9]
print(li1)
print(li1[0])
print(li1[-1])
print(li1[0] + li1[-1])  # 정수형끼리의 연산 가능

>>>
[1, 3, 5, 7, 9]
1
9
10

-----------------------------------------------------

# 슬라이싱

li1 = [10, 20, 30, 40, 50]
print(li1)
print(li1[0:3])

>>>
[10, 20, 30, 40, 50]
[10, 20, 30]

 

리스트 안에 리스트를 포함 할 수 있다.


li3 = [1, 2, 3, ['김사과', '오렌지', '반하나', ['🍕', '🍟', '🥩', '🥓']]]
print(li3[2])
print(li3[-1])
print(li3[-1][-2])  # 리스트 안의 데이터 인덱스
print(li3[-1][-1][-1])

>>>
3
['김사과', '오렌지', '반하나', ['🍕', '🍟', '🥩', '🥓']]
반하나
🥓

 

리스트의 데이터 변경

 

리스트안에 포함되어있는 데이터들의 수정, 추가, 삭제가 가능하다.

li1 = [10, 20, 30]
li1[1] = 100
print(li1)

>>> [10, 100, 30]
-----------------------------------------------------
li4 = [10, 20, 30, 40, 50]
li4[1:2] = ['😎', '😁', '🤣']
# 슬라이싱을 이용하여 요소를 추가한 경우, 리스트에 데이터만 포함
print(li4)

>>> [10, '😎', '😁', '🤣', 30, 40, 50]
-----------------------------------------------------

li4 = [10, 20, 30, 40, 50]
li4[1] = ['😎', '😁', '🤣']
# 인덱싱을 이용하여 요소를 추가한 경우, 리스트 안에 리스트를 만들고 포함
print(li4)

>>> [10, ['😎', '😁', '🤣'], 30, 40, 50]
-----------------------------------------------------

li5 = [100, 20 ,30 ,40, 50]
print(li5[1:3])
# 빈 리스트를 저장하면, 해당 요소가 삭제됨
li5[1:3] = []
print(li5)

>>>
[20, 30]
[100, 40, 50]
-----------------------------------------------------

# 리스트 데이터 삭제
li5 = [100, 20 ,30 ,40, 50]
print(li5)
del li5[2]
print(li5)

>>>
[100, 20, 30, 40, 50]
[100, 20, 40, 50]

 

리스트의 연산

 

+ 를 사용하여 리스트와 리스트를 결합할 수 있으며 ( 인플레이스 ), * 를 사용하여 리스트를 반복할 수 있다.

li6 = [10, 20, 30]
li7 = [40, 50, 60]
print(li6 + li7)
print(li7 + li6)  # 결합된 순서에 따라서, 리스트 요소가 나열된다.

>>>
[10, 20, 30, 40, 50, 60]
[40, 50, 60, 10, 20, 30]

li6 = [10, 20, 30]
li6 += [100, 200] # li6 = li6 + [100, 200]  # = li6 + [100, 200 ]
print(li6)

>>> [10, 20, 30, 100, 200]
-----------------------------------------------------

li6 = [10, 20, 30]
print(li6 * 3)

>>> [10, 20, 30, 10, 20, 30, 10, 20, 30]
* 인덱스를 이용하여 연산 시, 데이터 타입이 다를 경우, 오류가 발생한다.

li6 = [10, 20, 30]
print(li6[0] + li6[2])
li6[1] = '😎'
print(li6)

>>>
40
TypeError: unsupported operand type(s) for +: 'int' and 'str'

 

리스트의 함수와 메서드

 

len() : 객체의 길이를 반환

li6 = [10, 20, 30]
print(len(li6))

>>> 3 

append() : 리스트의 끝에 새로운 데이터를 추가 ( * 하나의 데이터만 가능 )

li6 = [10, 20, 30]
print(li6)
# 하나의 요소만 가능
li6.append(100)
print(li6)
# 여러 데이터가 포함된 리스트 타입의 데이터는 추가가 가능하다
li6.append([200, 300])
print(li6)

>>>
[10, 20, 30]
[10, 20, 30, 100]
[10, 20, 30, 100, [200, 300]]

extend() : append()와 달리, 한번에 여러 데이터를 추가할 수 있으며, 중괄호[ ]를 사용한다. ( 단일 요소도 포함 )

li6 = [10, 20, 30]
print(li6)
li6.extend([50])
print(li6)
li6.extend([100, 200, 300])
print(li6)

>>>
[10, 20, 30]
[10, 20, 30, 50]
[10, 20, 30, 50, 100, 200, 300]

pop() : 리스트의 "마지막" 데이터를 삭제하고, 삭제한 데이터를 반환

li6 = [10, 20, 30]
print(li6)
print(li6.pop())
print(li6)

temp = li6.pop()  # 데이터 "반환"되기 때문에, 변수에 지정이 가능하다
print(temp)

>>>
[10, 20, 30]
30
[10, 20]

30

insert(인덱스, 데이터) : 리스트의 특정 인덱스(위치)에 데이터를 "하나만" 추가

li6 = [10, 20, 30]
print(li6)

li6.insert(1, 100)
print(li6)
li6.insert(2, [1000, 2000])  # 리스트 추가가능
print(li6)

>>>
[10, 20, 30]
[10, 100, 20, 30]
[10, 100, [1000, 2000], 20, 30]

index() : 특정 값의 인덱스를 반환

li6 = [10, 20, 30]
print(li6.index(20))

>>>
1

* 해당 값이 없을 경우, ValueError: 100 is not in list 에러발생한다.

reverse() : 리스트의 순서를 역순으로 변경 (인플레이스)


li7 = [100, 50, 70, 60, 20]
print(li7)
li7.reverse()
print(li7)

>>>
[100, 50, 70, 60, 20]
[20, 60, 70, 50, 100]
# 슬라이스를 사용하여 리스트의 순서를 변경할 수 있다.
li7 = [100, 50, 70, 60, 20]
# 슬라이스의 형태는 [start:stop:step] 이며, step의 값을 생략할 경우, 1로 적용된다.
# start를 생략하면 -1로 간주
# stop을 생략하면 0으로 간주
print(li7[::-1])
# step이 -1이므로, 앞으로 하나씩 슬라이싱

>>> [20, 60, 70, 50, 100]

sort() : 리스트를 오름차순으로 변경

li7 = [100, 50, 70, 60, 20]
print(li7)
li7.sort()
print(li7)

>>>
[100, 50, 70, 60, 20]
[20, 50, 60, 70, 100]


# 문자열도 정렬이 가능하다. ( 아스키코드 or 유니코드 순서를 기준으로 정렬 ) 

li8 = ['Apple', 'apple', 'orange', 'banana', 'melon']
li8.sort()
print(li8)

>>> ['Apple', 'apple', 'banana', 'melon', 'orange']

li9 = ['김사과', '오렌지', '반하나', '이메론', '배애리']
li9.sort()
print(li9)

>>> ['김사과', '반하나', '배애리', '오렌지', '이메론']
# 내림차순으로 변경 시 ( 오른차순으로 변경 후, 역순으로 변경 )

li7 = [100, 50, 70, 60, 20]
print(li7)
li7.sort(reverse = True)  # reverse 값을 True로 지정하여 역순으로 변경
print(li7)

>>>
[100, 50, 70, 60, 20]
[100, 70, 60, 50, 20]

sorted() : 모든 데이터들을 정렬한 후, 반환 ( 오름차순 )

li7 = [100, 50, 70, 60, 20]
print(li7)
print(sorted(li7))
print(li7)

result = sorted(li7)
print(result)

>>>
[100, 50, 70, 60, 20]
[20, 50, 60, 70, 100]
[100, 50, 70, 60, 20]
[20, 50, 60, 70, 100]


# 내림차순으로 정렬 시

li7 = [100, 50, 70, 60, 20]
print(li7)
result = sorted(li7, reverse=True) # 내림차순
print(result)

>>>
[100, 50, 70, 60, 20]
[100, 70, 60, 50, 20]

count() : 리스트안의 특정 데이터의 갯수를 반환

li10 = [10, 20, 30, 50, 20, 40, 30, 20]
print(li10.count(20))
print(li10.count(100))

>>>
3
0

 


* 리스트 객체의 구성

리스트객체의구성

1번 : 변수 l이 PyListObject 리스트 객체를 가리키고 있습니다.


2번 : 이 리스트에는 4개의 요소가 들어 있으므로 리스트의 개수를 나타내는 ob_size가 4입니다.


3번 : ob_item이 각 리스트의 개별 요소들을 가리키는 '이름 없는 변수 집합'을 가리키고 있습니다. 이름 없는 변수들 역시 변수 l과 마찬가지로 각각 다른 객체들을 가리키고 있습니다.


4번 : allocated는 실제 할당된 메모리 버킷의 개수를 나타냅니다.
리스트에 요소가 추가 될 때 마다 메모리 할당을 하게 되면 성능저하가 발생할 수 있으므로 미리 필요한것 보다 많은 버킷들을 할당해 놓습니다. 위 이미지에서는 하나만 더 할당 되어 있지만 실제 코드를 보면 리스트의 사이즈에 따라 4 또는 8씩 증가합니다. 하지만 상세 구현은 파이썬 버전에 따라 다를 수 있으므로 실제 필요한 버킷의 개수보다 여유롭게 alllocated 사이즈를 유지합니다.


5번 : 리스트에 또다른 리스트가 포함 될 수 있습니다. 이렇게 되면 다시 똑같은 메모리 구조가 재귀적으로 생성 됩니다.