순서 자료구조

2023. 3. 1. 13:14Python/실전 예제로 배우는 파이썬 프로그래밍

자료구조

프로그래밍에 의해서 만들어진 객체가 메모리에 배정될 때, 기억공간에 적재되는 구조

 

■ 열거형 객체: 하나의 메모리 영역에 여러 개의 자료가 나열된 집합 자료구조

■ 자료구조: 열거형 객체의 자료구조 형태가 순서를 갖고 있는 순서 자료구조와 순서가 없는 비순서 자료구조로 구분됩니다. 순서와 비순서의 차이점은 참조변수의 색인으로 접근할 수 있으면 순서, 색인을 이용할 수 없으면 비순서로 구분합니다.

 

순서 자료구조

 

str

문자열 객체를 만들어주는 클래스

 

실습 str 클래스 객체 예시

# (1) str 클래스 형식
str_var = str(object='string')
print(str_var)
print(type(str_var))
print(str_var[0])
print(str_var[-1])

string
<class 'str'>
s
g

# (2) str 클래스 간편 형식
str_var2 = 'string'
print(str_var2)
print(type(str_var2))
print(str_var2[0])
print(str_var2[-1])

string
<class 'str'>
s
g

# (1) str 클래스 형식

str 클래스에 의해서 생성된 'string' 문자열 객체와 자료형 그리고 참조변수의 색인으로 첫 번째 문자와 오른쪽 마지막 문자가 참조되는 예문입니다.

 

# (2) str 클래스 간편 형식

str 클래스를 이용하지 않고, 간편 형식으로 'string' 문자열 객체가 생성되는 예문입니다.

 

리스트(list)

여러 개의 자료를 순서대로 적재하는 가변 길이 순차 자료구조를 생성하는 클래스

 

(1) 리스트 객체 특징

■ 순서 자료구조를 갖는 열거형 객체를 생성할 수 있습니다.

■ 다음 형식과 같이 대괄호([])안에 콤마(,)를 이용하여 순서대로 값을 나열합니다.

 

형식

변수 = [값1, 값2, .... 값n]

■ 값의 자료형은 숫자형, 문자형, 논리형 등을 함께 사용할 수 있습니다.

■ 색인(index)을 이용하여 자료를 참조할 수 있고, 슬라이싱, 연결, 반복, 요소 검사 등이 가능합니다.

■ 값을 추가, 삽입, 수정, 삭제가 가능합니다.

 

실습 단일 리스트 객체 예시

# (1) 단일 list 예
lst = [1, 2, 3, 4, 5]
print(lst)
print(type(lst))

for i in lst:
	print(lst[:i])	# i 전까지
    
[1, 2, 3, 4, 5]
<class 'list'>
[1]
[1, 2]
[1, 2, 3]
[1, 2, 3, 4]
[1, 2, 3, 4, 5]

# (1) 단일 리스트 예

1~5까지 5개의 원소를 갖는 lst 객체를 생성하고, list의 전체 원소와 자료형을 출력합니다. 단일 리스트란 하나의 리스트로만 구성된 리스트 형식을 의미합니다.

 

(2) 리스트 색인

리스트는 순서 자료구조이기에 색인을 이용하여 리스트의 원소를 참조할 수 있습니다.

 

실습 단일 리스트 색인 예시

# (2) 단일 list 색인
x = list(range(1, 11))
print(x)
print(x[:5])
print(x[-5:])
print('index 2씩 증가 ')
print(x[::2])	# 홀수 색인
print(x[1::2])	# 1부터 시작하는 짝수 색인

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[1, 2, 3, 4, 5]
[6, 7, 8, 9, 10]
index 2씩 증가 
[1, 3, 5, 7, 9]
[2, 4, 6, 8, 10]

# (2) 단일 리스트 색인

list(range(1, 11)) 명령어는 range 클래스에 의해서 열거형 객체를 생성한 후 리스트 객체로 변환하는 명령문입니다. 참조 변수 x를 출력하면 대괄호 안에 1~10의 원소를 갖는 열거형 객체가 출력됩니다.

 

(3) 중첩 list

리스트 내에 또 다른 리스트가 포함된 형식

 

실습 중첩 list 객체 예시

# (1) 단일 리스트 객체 생성
a = ['a', 'b', 'c']
print(a)

['a', 'b', 'c']

# (2) 중첩 리스트 객체 생성
b = [10, 20, a, 5, True, '문자열']	# 서로 다른 자료형
print(b[0])	# 10
print(b[2])	# ['a', 'b', 'c']	-> 중첩 list
print(b[2][0])	# a	-> 중첩 list 1번 원소
print(b[2][1:])	# ['b', 'c']	-> 중첩 list 2번 이후 원소

10
['a', 'b', 'c']
a
['b', 'c']

# (1) 단일 리스트 객체 생성

변수 a는 세 개의 영문자를 갖는 단일 list 객체가 생성됩니다.

 

# (2) 중첩 리스트 객체 생성

변수 b는 변수 a를 포함하고 있는 중첩 리스트 객체입니다. 중첩 리스트의 특정 원소를 참조하기 위해서는 b 변수의 색인과 a 변수의 색인을 순서대로 나열해야 합니다.

 

(4) 추가, 삭제, 수정, 삽입

리스트는 새로운 값을 원소로 추가할 수 있고, 기존 값을 삭제할 수 있습니다. 또한, 색인을 이용해서 특정 위치의 값을 수정할 수 있고, 삽입할 수 있습니다.  

 

실습 추가, 삭제, 수정, 삽입 예시

# (1) 단일 리스트 객체 생성
num = ['one', 'two', 'three', 'four']
print(num)	# ['one', 'two', 'three', 'four']
print(len(num))	# 4

['one', 'two', 'three', 'four']
4

# (2) 리스트 원소 추가
num.append('five')	# 추가
print(num)	# ['one', 'two', 'three', 'four', 'five']

['one', 'two', 'three', 'four', 'five']

# (3) 리스트 원소 삭제
num.remove('five')	# 삭제
print(num)

['one', 'two', 'three', 'four']

# (4) 리스트 원소 수정
num[3] = '4'	# 수정
print(num)

['one', 'two', 'three', '4']

# (5) 리스트 원소 삽입
num.insert(0, 'zero')	# 삽입
print(num)

['zero', 'one', 'two', 'three', '4']

# (1) 단일 리스트 객체 생성

변수 num은 세 개의 문자열을 갖는 단일 리스트 객체가 생성됩니다.

 

# (2) 리스트 원소 추가

리스트 객체에서 제공하는 append() 함수를 이용해서 새로운 값('five')을 추가합니다. 변수 num이 참조하는 열거형 객체의 끝 부분에 새로운 값이 추가됩니다.

 

# (3) 리스트 원소 삭제

리스트 객체에서 제공하는 remove() 함수를 이용해서 기존 값('five')을 삭제합니다.

 

# (4) 리스트 원소 수정

리스트의 색인을 이용하여 네 번째 위치의 값('four')이 값('4')으로 수정됩니다.

 

# (5) 리스트 원소 삽입

리스트의 색인을 이용하여 첫 번째 위치에 값('zero')을 삽입합니다.

 

(5) 리스트 연산

리스트는 사칙연산에서 제공되는 기호를 이용하여 결합(+)과 두 배 확장(*)이 가능합니다.

 

실습 리스트 연산 예시

# (1) 리스트 결합
x = [1, 2, 3, 4,]
y = [1.5, 2.5]
z = x + y	# new object
print(z)	# [1, 2, 3, 4, 1.5, 2.5]

[1, 2, 3, 4, 1.5, 2.5]

# (2) 리스트 확장
x.extend(y)	# x확장
print(x)	# [1, 2, 3, 4, 1.5, 2.5]

[1, 2, 3, 4, 1.5, 2.5]

# (3) 리스트 추가
x.append(y)	# x 추가
print(x)	# [1, 2, 3, 4, 1.5, 2.5, [1.5, 2.5]]

[1, 2, 3, 4, 1.5, 2.5, [1.5, 2.5]]

# (4) 리스트 두 배 확장
lst = [1, 2, 3, 4]	# list 생성
result = lst * 2	# 각 원소 연산 안됨
print(result)	# [1, 2, 3, 4, 1, 2, 3, 4]

[1, 2, 3, 4, 1, 2, 3, 4]

# (1) 리스트 결합

변수 x와 객체와 변수 y의 객체가 결합되어 새로운 변수 z의 객체가 생성됩니다.

 

# (2) 리스트 확장

변수 x의 객체를 변수 y의 객체로 확장합니다.

 

# (3) 리스트 추가

변수 x의 객체를 변수 y의 객체로 확장합니다.

 

# (4) 리스트 두 배 확장

변수 lst의 객체에 곱셈(*) 기호를 이용하면 lst 객체의 원소가 두 배로 확장되어 새로운 객체가 생성됩니다. 

 

(6) 리스트 정렬과 요소 검사

리스트의 원소가 숫자인 경우 오름차순 또는 내림차순으로 정렬(sort)할 수 있습니다. 만약 찾는 값이 있다면 True가 반환되고, 없으면 False가 반환됩니다.

 

실습 리스트 정렬과 요소 검사 예시

# (1) 리스트 정렬
print(result)	# [1, 2, 3, 4, 1, 2, 3, 4]
result.sort()	# 오름차순 정렬
print(result)	# [1, 1, 2, 2, 3, 3, 4, 4]
result.sort(reverse = True)	# 내림차순 정렬
print(result)	# [4, 4, 3, 3, 2, 2, 1, 1]

[1, 2, 3, 4, 1, 2, 3, 4]
[1, 1, 2, 2, 3, 3, 4, 4]
[4, 4, 3, 3, 2, 2, 1, 1]

# (2) 리스트 요소 검사
import random
r = []	# 빈 list
for i in range(5):
	r.append(random.randint(1, 5))
    
print(r)
if 4 in r:
	print('있음')
else:
	print('없음')
    
[5, 3, 5, 2, 3]
없음

# (1) 리스트 정렬

변수 result의 객체를 대상으로 sort() 함수를 적용하면 오름차순 정렬되고, reverse =True 인자를 추가하면 내림차순 정렬됩니다.

 

# (2) 리스트 요소 검사

변수 r은 빈 목록으로 생성된 리스트 객체를 참조합니다. 변수 r에 난수 4가 포함되어 있으면 True가 반환되어 '있음'이 출력되고, 없으면 False가 반환되어 '없음'이 출력됩니다.

 

■ scala 변수: 한 개의 값을 갖는 변수로 값의 크기를 가집니다. 

예) x = 10

■ vector 변수: 여러 개의 값을 갖는 변수로 값의 크기와 방향을 가집니다.

예) x = [10, 20, 30, 40, 50]

 

리스트 내포

리스트 내포(List comprehension)란 list 안에서 for와 if를 사용하는 문법을 의미합니다.

 

형식

변수 = [실행문 for 변수 in 열거형객체]

① for문에서 열거형객체의 원소 하나를 변수로 넘겨받습니다.

② 변수에 할당된 값을 실행문으로 처리합니다.

③ 처리된 결과를 변수에 순차적으로 추가(append)합니다.

 

리스트 내포의 두 번째 형식으로 리스트 안에 for와 if문을 함께 사용하여 반복을 수행하는 과정에서 조건에 만족하는 내용을 선택적으로 처리할 경우 유용하게 사용할 수 있습니다.

 

형식 

변수 = [실행문 for 변수 in 열거형객체 if 조건식

① for문에서 열거형 객체의 원소 하나를 변수로 넘겨받습니다.

② 변수에 할당된 값을 조건식으로 사용하여 비교 판단합니다.

③ 조건이 참(True)이면 변수에 할당된 값을 실행문으로 처리합니다.

④ 처리된 결과를 변수에 순차적으로 추가(append)합니다.

 

실습 리스트 내포 예시

# 형식1) 변수 = [ 실행문 for ]
x = [2, 4, 1, 5, 7]
# print(x ** 2)	# error

lst = [ i ** 2 for i in x ]	# x변량에 제곱 계산
print(lst)	# [4, 16, 1, 25, 49]

[4, 16, 1, 25, 49]

# 형식2) 변수 = [ 실행문 for if ]
# 1~10 -> 2의 배수 추출 -> i*2 -> list 저장
num = list(range(1,11))

lst2 = [ i*2 for i in num if i % 2 == 0 ]
print(lst2)

[4, 8, 12, 16, 20]

# 형식 1) 변수 = [ 실행문 for ]

변수 x의 각 원소에 제곱을 계산하기 위해서 변수 x에 직접 제곱(**) 연산자를 적용하면 오류(Error)가 발생합니다. 

 

# 형식 2) 변수 = [ 실행문 for if ]

변수 num에는 range 클래스에 의해서 생성된 1에서 10까지 10개의 숫자를 객체로 갖습니다.

 

튜플(tuple)

순차 자료구조라는 점에서 리스트 자료 구조와 많은 부분에서 유사합니다. 차이점은 읽기 전용으로 원소를 수정하거나 삭제할 수 없고, 리스트에 비해서 처리속도가 빠릅니다.

 

(1) 튜플 객체 특징

■ 순서 자료구조를 갖는 열거형 객체를 생성할 수 있습니다.

■ 다음 형식과 같이 소괄호(())안에 콤마(,)를 이용하여 순서대로 값을 나열합니다.

 

형식

변수 = (값1, 값2, .... 값n)

■ 값의 자료형은 숫자형, 문자형, 논리형 등을 함께 사용할 수 있습니다.

■ 색인(index)을 이용하여 자료를 참조할 수 있고, 슬라이싱, 연결, 반복, 요소 검사 등이 가능합니다.

■ 읽기 전용이기에 값을 추가, 삽입, 수정, 삭제가 불가능합니다.

■ 리스트보다 처리속도가 빠릅니다.

 

실습 튜플 객체 예시

# (1) 원소가 한 개인 경우
t = (10, )
print(t)

(10,)

# (2) 원소가 여러 개인 경우
t2 = (1, 2, 3, 4, 5, 3)
print(t2)

(1, 2, 3, 4, 5, 3)

# (3) 튜플 색인
print(t2[0], t2[1:4], t2[-1])

1 (2, 3, 4) 3

# (4) 수정 불가
# t2[0] = 10	# error

# (5) 요소 반복
for i in t2:
	print(i, end=' ')

1 2 3 4 5 3

# (6) 요소 검사
if 6 in t2:
	print("6 있음")
else:
	print("6 없음")
    
6 없음

# (1) 원소가 한 개인 경우

원소가 한 개인 경우 (10, ) 형식으로 원소 뒤에 콤마(,)를 붙여야 합니다.

 

# (2) 원소가 여러 개인 경우

6개의 원소를 갖는 변수 t2의 전체 원소가 출력되는 예문입니다.

 

# (3) 튜플 색인

튜플 색인은 리스트와 동일합니다.

 

# (4) 수정 불가

튜플의 원소는 수정, 삽입, 삭제 등이 불가능합니다. 만약 수정이나 삽입 등을 위해서 리스트 자료형으로 변환해야 합니다.

(예: lst = list(t2)) 

 

# (5) 요소 반복

리스트와 동일하게 for문에서 요소 반복이 가능합니다.

 

# (6) 요소 검사

리스트와 동일하게 if문을 이용하여 요소 검사가 가능합니다.

 

(2) 튜플 관련 함수

튜플 객체는 원소를 수정이나 삭제 등의 작업이 불가능하기에 객체에서 지원하는 함수는 리스트에 비해서 적습니다.

 

실습 튜플 관련 함수 예시

# (1) 튜플 자료형 변환
lst = list(range(1, 6))
t3 = tuple(lst)
print(t3)

(1, 2, 3, 4, 5)

# (2) 튜플 관련 함수
print(len(t3), type(t3))	# 5 <class 'tuple'>
print(t3.count(3))
print(t3.index(4))

5 <class 'tuple'>
1
3

# (1) 튜플 자료형 변환

변수 lst는 range 객체를 리스트 객체로 자료형이 변환된 객체를 참조합니다. 변수 t3는 튜플 객체로 변환된 객체를 참조하고 있습니다.

 

# (2) 튜플 관련 함수

변수 t3의 전체 원소의 길이와 자료형을 출력하고 있습니다.