본문 바로가기
SSAFY

[수업기록] 데이터 구조(1)

by 주니코니 2024. 7. 22.

240722 파이썬반

 

1. 데이터 구조란

- 여러 데이터를 효과적으로 사용, 저장, 관리를 위한 구조를 나눠 놓은 것

(str, list, dict 등)

- 데이터 구조 활용 :

문자열, 리스트, 딕셔너리 등 각 데이터 구조의 메서드를 가지고 있다 -> 호출

 

2. 메서드란(method)

- 객체에 속한 함수, 객체의 상태를 조작하거나 동작을 수행

- 메서드 특징 :

메서드는 클래스(class) 내부에 정의되는 함수를 의미

클래스란 파이썬에서 타입을 표현하는 방법으로 은연중에 사용해왔다 

print(type('ab')) #class <str>

 

- 즉 : 메서드는 어딘가(클래스)에 속해 있는 함수이며, 각 데이터 타입별로 다양한 기능을 가진 메서드가 존재한다

 

- 메서드 호출 방법

데이터 타입 객체.메서드()

 

1) 문자열 메서드

ex. 'hello'.capitalize() #Hello

 

 

2) 리스트 메서드 

ex. numbers = [1,2,3]
numbers.append(4)
print(numbers) #[1,2,3,4]

 

 

3. 시퀀스 데이터 구조

1) 문자열 조회/탐색/검증 메서드

str.find(x) #x의 첫 번째 위치(인덱스)를 반환, 없으면 -1 반환
text = 'bananaaa'
print(text.find('a')) #1
print(text.find('z')) #-1

str.index(x) #x의 첫 번째 위치를 반환, 없으면 오류 발생
print(text.index('z'))
#ValueError: substring not found

str.isupper() #(모두) 대문자여부 #반환값 True/False
string1 = 'HELLO'
string2 = 'Hello'
print(string1.isupper()) #True
print(string2.isupper()) #False

str.islower() #소문자 여부 

str.isalpha() #알파벳 문자 여부 #유니코드상 letter #한국어도 포함
string1 = 'HELLO'
string2 = '741aksks바아2'
string3 = '안녕'
print(string1.isalpha()) #T
print(string2.isalpha()) #F
print(string3.isalpha()) #T

 

 

2) 문자열 조작 메서드(새 문자열 반환 == 원본 수정 불가)

문자열은 불변이다

string.replace(old, new[,count]) #바꿀 대상 글자를 새로운 글자로 바꿔 반환
#대괄호 : 모든 프로그래밍 언어에서의 통일 -> 선택인자 의미
text = 'Hello, world! world world'
new = text.replace('world','python')
print(new) #Hello, python! python python

text = 'Hello, world! world world'
new = text.replace('world','python',1) #Hello, python! world world
print(new)


s.strip([chars]) #문자열의 시작과 끝에 있는 공백 혹은 지정한 문자를 제거 
text = '  Hello, world!  '
print(text.strip())
'Hello, world!


s.split(sep=None, maxsplit=-1) #리스트로 반환
text = 'Hello, world!'
print(text.split(','))
#['Hello', ' world!'] #world앞 공백 
print(text.split()) #['Hello,', 'world!']


'separator'.join(iterable)
words = ['Hello', 'world!']
new_text = '-'.join(words)
#Hello-world!

 

text = 'heLLo, woRld!'

# capitalize
print(text.capitalize())
#Hello, world!#앞 대문자, #뒤 다 소문자로 변환

#title
text2 = text.title()
print(text2)
#Hello, World!#문자열 간 공백 기준으로 공백 다음 문자열도 대문자로

# upper
text3 = text.upper()
print(text3)
#HELLO, WORLD!

#lower
text4 = text.lower()
#hello, world!
print(text4)


# swapcase #대소문자 전환
text5 = text.swapcase()
print(text5)
#HEllO, WOrLD!

 

 

3)리스트 값 추가 및 삭제 메서드

리스트 : 가변

L.append(x) 리스트 마지막에 추가
my_list = [1, 2, 3]
my_list.append(4)
print(my_list) #[1,2,3,4]
print(my_list.append(4)) #None, 리스트는 가변, 반환이 없다, 반환없는 함수 None 리턴 ❤



L.extend(m) #iterable m의 모든 항목들을 리스트 끝에 추가 (+=와 같은 기능)
my_list = [1, 2, 3]
my_list.extend([4,5,6]) #하나씩 넣을 때
print(my_list) #[1, 2, 3, 4, 5, 6]

my_list.extend(5) #-> append #extend 정수 하나를 넣을 수 없다
print(my_list) #TypeError: 'int' object is not iterable

my_list.append([9,9,9]) #리스트 통째로 넣을 때
print(my_list) #[1, 2, 3, 4, 5, 6, [9, 9, 9]]

my_list.extend([5])
my_list #[1,2,3,4,5,6,5]

extend, append 인자 하나씩만 받을 수 있음


L.insert(i,x) #리스트 인덱스 i에 항목 x 삽입
my_list = [1, 2, 3]
my_list.insert(0,2)
print(my_list)
#[2, 1, 2, 3]


L.remove(x) #리스트 가장 왼쪽에 항목(첫번째) x를 제거, 항목 존재안할 경우 value error
my_list = [1, 2, 3]
my_list.remove(2)
print(my_list) #[1, 3]


L.pop() #리스트 가장 오른쪽 항목(마지막) 제거
my_list = [1, 2, 3, 4, 5]
item1 = my_list.pop()
print(item1) # 반환값 존재 #5
print(my_list) #[1, 2, 3, 4]

item2 = my_list.pop(0) #1
print(my_list) #[2, 3, 4]



# clear
my_list = [1, 2, 3]
my_list.clear()
print(my_list)
#[]

 

 차이가 헷갈려서 재정리

append와 extend의 차이 

#%%
test = [1,2]
test.append([2])
print(test)

test.extend([2,1,1])
print(test)

test.append({3})
print(test)

test.extend({3})
print(test) # 3

test.append([1,2])
print(test)


#[1, 2, [2]]
#[1, 2, [2], 2, 1, 1]
#[1, 2, [2], 2, 1, 1, {3}]
#[1, 2, [2], 2, 1, 1, {3}, 3]
#[1, 2, [2], 2, 1, 1, {3}, 3, [1, 2]]

 

 

 

4) 리스트 탐색 및 정렬 메서드

L.index(x) #인덱스 반환
my_list = [1, 2, 3]
index = my_list.index(2)
print(index) # 1


L.count(x) 
my_list = [1, 2, 2, 3, 3, 3]
print(my_list.count(1)) #1


L.reverse() #정렬x #리스트 순서를 역순으로 변경
my_list = [1, 3, 2, 8, 1, 9] #원본을 뒤집음
print(my_list.reverse()) #None
print((my_list))  #[9, 1, 8, 2, 3, 1]


L.sort(x) #리스트 정렬 #매개변수 활용
my_list = [3, 2, 100, 1]
my_list.sort()  #디폴트는 오름차순
print(my_list)
#[1, 2, 3, 100]

my_list = [3, 2, 100, 1]
my_list.sort(reverse=True)  #매개변수
print(my_list)
#[100, 3, 2, 1]

 

 

4. 데이터 타입과 복사

데이터 타입에 따라 복사방법이 다르다 ✔ ✔ ✔ ✔

# 할당(Assignment) == 주소 받기 == 객체 참조(주소) 복사하는 것 
# 가변데이터 타입
a = [1,2,3,4]
b = a #b는 a로부터 주소를 받은 것

b[0] = 100 #[100, 2, 3, 4]

print(b) 
# 과연 a는 변경이 되었을까?
print(a)  # a, b 복사x, # 젠장~ 변경이되어있네~~ 안되어있을줄알았는데~~~~~~
#[100, 2, 3, 4]

#------------------------------------

#불변 데이터 타입이라면?
a = 20 
b = a
b = 10 #재할당

print(a) #20
print(b) #10 


# 가변 데이터 복사 유형
# 얕은 복사(shallow copy)
# 슬라이싱으로 새로운 리스트 생성
a = [1,2,3,4]
b = a[:] #새로운 리스트 생성 #주소 다름

b[0] =100
print(a) #[1, 2, 3, 4]
print(b) #[100, 2, 3, 4]


a = [1,2,3,4]
b = a[:]
c = a.copy() #[:]과 동일

b[0] =100
c[0] = 10
print(a) #[1, 2, 3, 4]
print(b) #[100, 2, 3, 4]
print(c) #[10, 2, 3, 4]


#왜 얕은복사라고 할까?
# 얕은 복사의 한계
a=[1,2,[3,4]]
b = a[:] #중첩된 리스트는 같은 주소를 받는다 => 얕은 복사라 한다
b[2][1] =100 
print(a)#[1, 2, [3, 100]]
print(b)#[1, 2, [3, 100]]
#a, b 주소는 다르지만 요소에 대한 각각의 주소는 같다

b[0] = 99
print(a) #[1, 2, [3, 100]]
print(b) #[99, 2, [3, 100]]
즉 a와 b의 주소는 다르지만 내부 객체의 주소가 같기에 함께 변경됨

# 깊은 복사(Deep copy)
import copy
a=[1,2,[3,4]]
b= copy.deepcopy(a)
b[2][1]=100
print(a) #[1, 2, [3, 4]] # 다른 주소
print(b) #[1, 2, [3, 100]] #다른 주소
즉 내부에 중첩된 문자열까지 새로운 객체 주소를 참조하도록 함

 

 

5. 문자열에 포함된 문자들의 유형을 판별하는 메서드

isdecimal() : 문자열 모두 오직 일반적인 십진수 숫자(0-9)만 True로 인식
isdigit() : 위와 비슷, 유니코드 숫자도 인식, 지수 표현(²)도 True로 인식
#'²'.isdigit(): True 
isnumeric() :위와 비슷, 몇가지 추가적 유니코드 인식(분수, 루트, 지수 기호, 로마숫자, 일반숫자 등)