[TIL: 0126] 데이터 구조 및 복사

ryun·2023년 1월 26일
0

TIL

목록 보기
9/34

문자열이 주어지면 숫자, 문자, 기호가 몇 개인지 출력하는 함수를 만들어라

def check(input_str):
	char_count = 0
    digit_count = 0
    symbol_count = 0
    
    for char in input_str:
    	if char.isalpha():
        	char_count += 1
        elif char.isdigit():
        	digit_count += 1
        else:
        	symbol_count += 1
            
    return (char_count, digit_count, symbol_count)
    
input_str = '123#$%aiden_snow"
char_count, digit_count, symbol_count = check(input_str)
print(f"char: {char_count}, digit: {digit_count}, symbol: {symbol_count}")

📍 데이터 구조

자료구조를 학습할 때는 데이터 구조와 데이터 구조를 활용한 연산이 중요하다

플레이리스트는 선형구조 (순차, 연결 리스트)
팔로우리스트는 그래프 (비선형 구조)

Set

  • 중복되는 요소가 없이 순서에 상관없는 데이터들 묶음
    순서가 없기 때문에 인덱스를 이용한 접근이 불가능

  • 수학에서의 집합
    집합 연산이 가능하다

  • 가변 자료형으로 요소 삽입 변경, 삭제 가능

  • add(ele)
    셋에 값을 추가

  • update(*others)
    여러 값을 추가
    중복된 값은 1개로만 들어간다

  • discard(ele)
    삭제하고 없어도 에러가 발생하지 않음

  • pop()
    임의의 원소를 제거해 반환

  • clear()
    모든 항목을 제거

Dictionary

  • 키-값 쌍으로 이워진 자료형
  • dic.keys()
  • dic.values()
  • dic.get(k)
    딕셔너리 키 k의 value 값을 반환
    dic['k']가 없으면 에러가 난다
    dic.get(k)가 없으면 None을 반환한다
  • dic.get(k, v)
    dic의 키 k가 없을 경우 v를 반환해라
    dic['k'] 보다는 get을 더 추천
    없을 경우 대비한 값을 미리 지정해놓을 수 있어서 if 문 활용도 가능
  • dic.items()
    뷰(반복 가능한 객체)를 반환한다
  • dic.pop()
    제거 후 반환

📍 얕은 복사와 깊은 복사

기존 변수 사용 과정에서의 문제점

  • 하나의 기억에, 하나의 주소가 필요
  • 즉, 100개 저장하려면 주소가 100개가 필요하다

여러 기억을 하나의 주소로 찾아갈 수 있도록 할 수 없나?
연속적인 공간에 데이터가 저장되도록 하면
맨 처음 기억의 주소만 가지고 있으면 된다

얕은 복사

같은 주소를 갖는다

  • 할당
    대입 연산자(=)대입연산자(=)를 통한 복사는 해당 객체에 대한 객체 참조를 복사
    *참조는 주소값을 가리킨다

  • slice 연산자를 활용해서 같은 원소를 가진 리스트지만 연산된 결과를 복사 (다른 주소)
    어떤 의미에서는 깊은 복사로도 볼 수 있다슬라이싱을 하는 리스트는 같은 원소를 가진 리스트지만, 다른 주소에 복사해준다
    왜 이게 얕은 복사인지 아래에서 설명

  • 얕은 복사 주의사항
    복사하는 리스트의 원소가 주소를 참조하는 경우
    a라는 변수에서 3개의 원소가 들어갈 자리가 필요, a는 시작하는 곳을 가리키고 있다, 첫 자리는 1, 두 번째 자리는 2, 세 번째 자리는 list가 저장이 되지 않는다. 따라서 그 리스트는 또 다른 주소에 저장해놓는다

list a, b를 저장할 공간을 따로 만들어서 저장 그 저장공간의 시작하는 주소를 아까 세 번째 자리에 저장 (주소값을 저장)
이 주소를 찾았다면 리스트 a, b 가 들어있다

a[:]
a라는 원소들을 복사해서 새로운 메모리에 할당
메모리 다른 공간에 1차원적으로 복사가 되긴 하지만 참조하는 주소값 까지 복사가 되진 않는다!
깊은 복사는 참조(주소값)까지 복사가 되어야 하는 것이다

슬라이스 연산자[:]를 사용하면 깊은 복사가 완벽하게 된다?
아니다.
메모리의 다른 공간에 1차원적으로 복사가 되긴 하지만 참조까지 복사가 되지는 않는다 !주의!

깊은 복사

다른 주소를 갖는다

깊은 복사가 되려면 참조까지도 복사가 되어야 한다 > deepcopy
(아래의 리스트 까지도)

📍 결론

  • 리스트를 복사하고 싶은 욕망이 든다면
    무조건 print를 찍어보기
  • 무조건 딥카피하면 메모리 용량이 증가한다


추가 정보

특정 조건에서는 주소 값이 동일하다 (파이썬의 특징)

얕은 복사가 부작용이 있을 수도 있다

복사 정리

  1. 단순 복사 (할당)
  • 완전히 동일한 메모리 주소에 담긴 객체를 가리킴
  1. 얕은 복사
  • 해당 객체의 주소만을 복사
  • 객체 안의 객체, 내부 객체는 원본과 동일한 주소를 가리키는 객체
  1. 깊은 복사
  • 새로운 자료공간(메모리 공간)을 갖는다
  • 객체 안의 객체, 내부 객체들 까지고 모두 Copy

0개의 댓글