자료구조 - 리스트

밤비나·2023년 3월 18일

자료구조(Data structure)

자료구조(Data Structure)란 데이터를 효율적으로 저장, 관리, 검색하기 위한 방법을 제공하는 일련의 알고리즘, 규칙, 저장 방식 등을 의미한다. 프로그래밍에서 자료구조는 데이터를 적절하게 조작할 수 있도록 해주는 중요한 역할을 한다.

우리 주변에는 다양한 자료구조들이 존재한다. 예를 들어, 우리가 일상 생활에서 사용하는 책장은 책을 저장하고 검색하기 위한 자료구조의 일종이다. 책장은 책을 수직으로 늘어놓은 형태로 데이터를 저장하며, 필요한 책을 찾을 때는 인덱스(책 이름, 저자 등)를 사용하여 빠르게 검색할 수 있다.

프로그래밍에서도 이와 유사하게 다양한 자료구조를 사용한다. 대표적인 자료구조로는 배열(Array), 연결 리스트(Linked List), 스택(Stack), 큐(Queue), 트리(Tree), 해시 테이블(Hash Table) 등이 있다. 각각의 자료구조는 특정한 데이터를 저장하고 처리하는데 최적화된 구조를 가지고 있다.

자료구조를 사용함으로써 데이터를 보다 효율적으로 관리할 수 있으며, 알고리즘의 실행 속도를 개선할 수 있다. 또한 자료구조를 잘 활용함으로써 문제를 보다 직관적으로 해결할 수 있다.

하지만, 어떤 자료구조를 선택하느냐에 따라 프로그램의 실행 속도가 크게 달라질 수 있으므로, 자료구조를 선택할 때는 특정 문제에 최적화된 구조를 선택하는 것이 중요하다. 또한, 자료구조를 학습할 때는 각 구조의 특징과 장단점, 그리고 사용 예시를 잘 이해하는 것이 필요하다.


리스트

리스트(List)는 파이썬에서 가장 기본적인 데이터 구조 중 하나이다. 순서가 있는 데이터의 집합이며, 동일한 자료형의 원소들로 구성된다. 파이썬에서 리스트는 대괄호([])로 표현하며, 각 원소는 쉼표로 구분된다.

  • 리스트를 이용하여 데이터를 추가하거나 삭제하고, 데이터를 정렬하거나 검색하는 등의 작업을 수행할 수 있다.
list1 = [1, 2, 3, 4, 5]  # 정수형 리스트
list2 = ['apple', 'banana', 'cherry']  # 문자열 리스트
list3 = [1, 'apple', 3.14, True]  # 혼합형 리스트
  • 리스트는 인덱스(index)를 사용하여 각 원소에 접근할 수 있다. 인덱스는 0부터 시작하며, 대괄호 안에 원소의 위치를 지정하여 접근한다.
list1 = [1, 2, 3, 4, 5]
print(list1[0])  # 1 출력
print(list1[2])  # 3 출력
  • 리스트에 새로운 원소를 추가할 때는 append() 메서드를 사용한다. append() 메서드는 리스트의 마지막에 원소를 추가한다.
list1 = [1, 2, 3, 4, 5]
list1.append(6)
print(list1)  # [1, 2, 3, 4, 5, 6] 출력
  • insert() 함수는 리스트의 지정한 위치에 새로운 요소를 삽입함
numbers = []
numbers.insert(0, 0)
numbers.insert(2, 6)
print(numbers)
  • extend() 메소드는 다른 리스트나 이터러블(iterable) 객체의 모든 항목들을 현재 리스트에 추가한다. 이 때 추가된 항목들은 리스트의 가장 끝에 위치하게 된다.
a = [1, 2, 3]
b = [4, 5, 6]
a.extend(b)
print(a) # [1, 2, 3, 4, 5, 6]

a = [1, 2, 3]
s = "456"
a.extend(s)
print(a) # [1, 2, 3, '4', '5', '6']
  • 리스트에서 원소를 삭제할 때는 del 키워드를 사용한다. del 키워드를 사용하여 리스트에서 원소를 삭제하면, 해당 원소의 인덱스 이후의 원소들의 인덱스가 하나씩 앞으로 당겨진다.
list1 = [1, 2, 3, 4, 5]
del list1[2]
print(list1)  # [1, 2, 4, 5] 출력

삭제 차이점

  • remove(): 리스트에서 특정 값을 삭제. 삭제할 값이 여러 개일 경우, 첫 번째로 발견된 값만 삭제. 만약 삭제할 값이 리스트에 존재하지 않는 경우 ValueError가 발생.
my_list = [1, 2, 3, 2, 4]
my_list.remove(2)
print(my_list) # [1, 3, 2, 4]
  • pop(): 리스트에서 특정 인덱스의 값을 삭제. 인덱스를 지정하지 않으면 리스트에서 마지막 값이 삭제. 삭제한 값을 반환.
my_list = [1, 2, 3, 4]
popped_item = my_list.pop(1)
print(my_list) # [1, 3, 4]
print(popped_item) # 2
  • del: 리스트에서 특정 인덱스의 값을 삭제. pop() 함수와 달리 삭제한 값을 반환하지 않는다. 또한, 슬라이스를 이용해서 리스트의 일부를 삭제하는 것도 가능.
my_list = [1, 2, 3, 4]
del my_list[1]
print(my_list) # [1, 3, 4]

my_list = [1, 2, 3, 4, 5]
del my_list[1:3]
print(my_list) # [1, 4, 5]

즉, remove() 함수는 값으로 삭제하고자 하는 경우에 사용하며, pop() 함수는 인덱스로 삭제하고자 하는 경우에 사용한다. del 키워드는 remove()와 pop()과는 다르게 슬라이스를 이용한 일괄 삭제가 가능하고 반환값이 없다.


  • in 키워드를 사용하여 리스트에서 원소를 검색할 때, 해당 원소가 리스트에 포함되어 있는지를 검사하는 것 외에도 해당 원소가 몇 번째 인덱스에 위치해 있는지를 알 수 있다. 이는 index() 메소드를 사용하여 구할 수 있다.
my_list = ['apple', 'banana', 'grape', 'orange']

# 'banana'이 리스트에 있는지 검사
if 'banana' in my_list:
    print('banana is in the list')

# 'banana'의 인덱스를 구함
banana_index = my_list.index('banana')
print('banana is at index', banana_index)

'''
banana is in the list
banana is at index 1
'''
  • sort() 메서드는 리스트 내의 요소를 오름차순으로 정렬해주는 메서드이다. 기본적으로는 오름차순 정렬이지만, reverse=True 파라미터를 추가해주면 내림차순으로 정렬할 수도 있다.
numbers = [3, 1, 4, 1, 5, 9, 2, 6, 5]
numbers.sort()
print(numbers)  # [1, 1, 2, 3, 4, 5, 5, 6, 9]

numbers.sort(reverse=True)
print(numbers)  # [9, 6, 5, 5, 4, 3, 2, 1, 1]
  • reverse() 메서드는 리스트 내의 요소의 순서를 반대로 뒤집어주는 메서드이다.
numbers.reverse()
print(numbers) 

슬라이싱

리스트의 문자열 슬라이싱은 리스트의 각 요소들이 문자열인 경우 해당 문자열에 대해서 슬라이싱이 가능하다.

my_list = ['apple', 'banana', 'cherry', 'date']
my_list[0][1:3]
# 'pp'

my_list[1][2:]
# 'nana'

my_list[2][:5]
# 'cherr'
  • 슬라이싱을 이용한 아이템 변경
my_list = [1, 2, 3, 4, 5]
my_list[1:4] = [6, 7, 8]
#[1, 6, 7, 8, 5]

my_list[1:3] = [9, 10, 11, 12]
# [1, 9, 10, 11, 12, 8, 5]
  • slice()함수는 슬라이스를 지정하기 위한 객체를 반환한다. 시작 인덱스, 끝 인덱스, 간격(step)을 지정해 이용한다.
my_list = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
s = slice(1, 5)
sub_list = my_list[s]
print(sub_list)

# [1, 2, 3, 4]

  • 리스트에서 * 연산자를 사용하면 리스트의 요소를 복사하여 새로운 리스트를 생성한다.
a = [1, 2, 3]
b = a * 2
print(b)  # [1, 2, 3, 1, 2, 3]
  • 리스트에서 index() 메서드를 사용하면 특정한 값의 인덱스를 찾을 수 있다.
a = [1, 2, 3, 1, 2, 3]
print(a.index(2))  # 1
  • count() 함수는 리스트에서 특정 값의 개수를 세는 함수이다. 리스트에서 해당 값이 몇 개 있는지 세어서 반환한다.
fruits = ['apple', 'banana', 'kiwi', 'apple', 'banana', 'orange', 'apple']

fruits.count('apple')
# 3

그 외 예제

my_list = ['apple', 'banana', 'grape', 'orange']

# 리스트의 끝에 'kiwi' 추가
my_list.append('kiwi')
print(my_list)

# 'banana' 다음에 'pear' 추가
my_list.insert(2, 'pear')
print(my_list)

# 'grape' 삭제
my_list.remove('grape')
print(my_list)

# 인덱스 1의 원소('banana') 삭제
del my_list[1]
print(my_list)

fruits = ['apple', 'banana', 'cherry']

for fruit in fruits:
  print(fruit)

'''
apple
banana
cherry
'''

numbers = [1, 2, 3, 4, 5]
i = 0

while i < len(numbers):
  print(numbers[i])
  i += 1

'''
1
2
3
4
5
'''

fruits = ['apple', 'banana', 'cherry', 'orange']

i = 0
while i < len(fruits):
    print(fruits[i])
    i += 1
'''
apple
banana
cherry
orange
'''

# for문을 이용하면 리스트의 아이템을 자동으로 참조
students = [[1,17],[2,21],[3,25],[4,27],[5,29],[6,27]]

max_cnt = students[0][1]
min_cnt = students[0][1]
max_class = students[0][0]
min_class = students[0][0]
sum = 0

for classNo, cnt in students:
    print(f'{classNo}학년 학생수 : {cnt}')
    sum += cnt

    if cnt > max_cnt:
        max_cnt = cnt
        max_class = classNo

    if cnt < min_cnt:
        min_cnt = cnt
        min_class = classNo

print(f'전체 학생 수 : {sum}')
print(f'평균 학생 수 : {int(sum/len(students))}')
print(f'가장 많은 학년 : {max_class}학년 ({max_cnt}명)')
print(f'가장 적은 학년 : {min_class}학년 ({min_cnt}명)')
'''
1학년 학생수 : 17
2학년 학생수 : 21
3학년 학생수 : 25
4학년 학생수 : 27
5학년 학생수 : 29
6학년 학생수 : 27
전체 학생 수 : 146
평균 학생 수 : 24
가장 많은 학년 : 5학년 (29명)
가장 적은 학년 : 1학년 (17명)
'''

minScore = 60
scores =[
    ['국어',58],
    ['영어',77],
    ['수학',87],
    ['과학',92],
    ['국사',50],
]

for subject in scores:
    if subject[1] < minScore:
        print(f'과락 과목 : {subject[0]}, 점수 : {subject[1]}')

enumerate() 함수

enumerate() 함수는 반복 가능한 객체(리스트, 튜플, 문자열 등)를 입력받아 인덱스와 함께 순차적으로 자료를 반환하는 객체를 리턴한다. 즉, 반복 가능한 객체를 인자로 받아서 인덱스와 해당 인덱스의 요소를 튜플 형태로 반환해주는 역할을 한다.

주로 반복문에서 리스트나 튜플 등의 객체의 인덱스를 사용하고 싶을 때, enumerate() 함수를 이용하여 코드를 작성한다.

fruits = ['apple', 'banana', 'cherry']
for index, value in enumerate(fruits):
    print(index, value)
    
    
'''
# 튜플 형태로 값을 반환
0 apple
1 banana
2 cherry
'''
profile
씨앗 데이터 분석가.

0개의 댓글