BootCamp/모두의연구소:오름캠프

23.01.05

혼복필 2024. 1. 5. 17:02
728x90
300x250
SMALL

리스트 (List)

= 가변적(mutable)이고 순서가 있는 시퀀스 자료형

위치의 특성을 가지고 있어 정렬이 가능하며 가변적이란 특성 때문에 원소들은 생성 후에도 변경, 추가, 삭제가 가능

생성 방법은 대괄호([]) 안에 쉼표(,)로 구분된 데이터들을 넣으면 됨

 

리스트의 수정 및 다차원 리스트

항목의 변경이 가능하며, 다양한 자료형을 함께 담을 수 있음

리스트 안에 다른 리스트를 담아 다차원 리스트 구성 가능

= 리스트와 달리 문자열은 불변(immutable), 내용 변경을 원할 땐 새로운 문자열을 생성해야 함

 

리스트의 연산

덧셈 = 두 리스트를 연결

곱셈 = 리스트를 여러번 반복

(중첩되지 않은 리스트의 곱셈은 값이 하나가 변경되어도 다른 값들이 변경되지 않음)

 

리스트 인덱싱

문자열처럼 순서가 있기에 인덱싱을 통해 각 항목에 접근 가능

첫 순서는 0부터 시작하며 마지막은 -1

인덱싱의 범위가 벗어나면 IndexError를 호출함

 

리스트 슬라이싱

일부분을 추출하고 싶을 때 인덱스를 사용하여 잘라냄

[start:stop:step] 형태로 사용하며 step는 기본적으로 1이며 생략 가능함

슬라이싱을 2번 또는 n번 사용하여 값 반환 가능

리스트 슬라이싱은 범위를 벗어나도 Error을 발생시키지 않음

 

까지가 어제의 내용이였습니다 :)

오늘은 리스트의 구조 특징부터 알아가 보았습니다.

 

리스트 메모리 구조

연속된 메모리 공간에 원소들을 저장하진 않음

단, 원소들은 참조를 통해 다양한 위치에 저장된 객체를 가리킴 (= 다양한 타입의 데이터를 동시 저장 가능)

리스트의 메모리 구조를 이해하기 위해 Python의 객체 저장 방식을 이해해야 함

Python = 모든 것을 객체로 취급

= 정수, 실수, 문자열, 리스트, 튜플, 딕셔너리 등 모든 데이터 타입이 객체로 관리된다는 것을 의미

리스트는 객체들의 참조를 저장하는 컨테이너

따라서 리스트의 각 요소는 실제 값을 저장한 것이 아닌 해당 객체를 참조하는 주소를 저장함

 

 

왼쪽은 Python의 메모리 구조, 오른쪽은 다른 언어에서의 메모리 구조입니다.

(Python에서 각 객체의 주소들은 일반적으로 연속적이지 않음)

 

메모리 효율성과 성능

다양한 데이터 타입의 원소를 동일한 리스트에 저장할 수 있음

데이터의 추가 및 삭제가 다른 언어에 비해 비교적 효율적

= 하지만 참조를 저장하기 위한 추가적인 메모리가 필요,

데이터가 연속적인 메모리 공간에 저장되지 않아 캐시의 지역성(cache locality)이 떨어짐

 

+ 캐시의 지역성 (cache locality)

컴퓨터의 메모리는 여러 계층으로 구성되어 있는데 이 중에서 CPU에 가장 가까운 메모리를 '캐시 메모리'라고 함

이 캐시 메모리는 매우 빠르지만 용량이 작음, 컴퓨터가 빠르게 데이터에 접근하려면 그 데이터가 가까운 곳에 모여 있어야 함

캐시 지역성은 데이터가 얼마나 가까이 모여 있는지를 나타내고 Python List는 메모리가 모여있지 않기 때문에, 때로는 느릴 수 있음

 

= 다양한 데이터 타입과 동적인 크기 변경을 지원하기 위한 트레이드-오프(trade-off)로 일부 메모리 및 성능 효율성을 포기함

 

+ 트레이드 오프 (trade-off)

어떤 것을 얻기 위해 다른 것을 포기함을 의미

 

동적 배열

내부적으로 동적 배열로 구현

공간을 초과한 데이터를 저장할 경우 자동으로 더 큰 메모리 공간을 확보하고 기존 데이터를 복사하는 방식으로 동작함

 

접근

1. 인덱스를 통한 접근

= 인덱스에 위치한 요소에 접근하는 시간 복잡도는 O(1), 시작 주소에서 오프셋(offset) 만큼 이동해서 해당 위치에 접근

2. 슬라이싱을 통한 접근

= 부분 리스트를 얻는 연산의 시간 복잡도는 O(k), 여기서 k는 슬라이스의 길이를 의미함

3. 검색을 통한 접근

= 특정 요소를 찾는 시간 복잡도는 O(n)

4. 마지막 요소 접근

= 끝에서 요소에 접근하는 것도 O(1)의 시간 복잡도를 가짐, 인덱스가 음수일 경우 끝에서부터 요소를 참조

 

리스트 메서드를 학습하기 전에 강사님이 몸이 안 좋으셔서 다른 강사님으로 바뀌었어요.

그래서 이론은 제가 공부하고 정리하여 요약하였습니다 :)

 

리스트 메서드

1. append() : 리스트의 끝에 값을 추가

2. clear() : 리스트의 모든 항목을 삭제

3. copy() : 리스트의 얕은 복사를 생성 (동일한 값을 가진 새로운 리스트를 반환)

4. count() : 특정 값이 리스트에 몇 번 포함되어 있는지 카운트

5. extend() : 리스트에 다른 리스트나 순회 가능한(iterable) 항목들을 추가

6. index() : 주어진 값을 찾아 해당 값은 위치를 반환, str 메서드에서 index와 함께 다룬 find메서드는 리스트에 없음

7. insert() : 주어진 위치에 값을 삽입

8. pop() : 리스트의 특정 위치에 있는 값을 반환하고 해당 값을 리스트에서 삭제함

9. remove() : 리스트에서 첫 번째로 발견되는 주어진 값을 삭제

10.1 reverse() : 리스트의 항목들 순서를 뒤집음, 원래의 리스트를 변경하고 아무것도 반환하지 않음 (None 반환)

10.2 reversed() : 역순으로 새로운 이터러블 객체를 반환

11.1 sort() : 리스트를 자체 정렬, 원래의 리스트를 변경하고 아무것도 반환하지 않음 (None 반환)

11.2 sorted() : 새로운 리스트를 반환, 원래의 리스트는 변경되지 않음

 

리스트 마무리 하고 튜플로 넘어가 보겠습니다.

 

튜플 (Tuple)

= 불변(immutable)하고 순서가 있는 시퀀스 자료형

리스트와 유사하게 여러 개의 데이터를 하나로 묶어서 사용할 수 있지만, 한 번 생성된 튜플은 내부 값은 변경이 불가

(튜플 내부에 리스트나 다른 튜플 생성 가능, 함께 다양한 타입의 데이터 저장 가능)

(학번, 이름, 주민등록번호와 같이 변경되면 안 되는 정보를 다룰 때 사용)

생성 방법은 소괄호()를 사용하며 쉼표(,)로 구분된 데이터를 넣음

 

튜플 특징

1. 변경이 불가능 (immutable)

= 참조값은 가리키고 잇는 값, 튜플 안에 변경 가능한 자료형을 넣으면 값이 변경될 수 있음

2. 왜 사용할까?

= 데이터의 안정성과 리스트에 비하면 더 빠른 처리 속도

 

튜플의 연산

덧셈 = 두 튜플을 연결

곱셈 = 튜플을 여러 번 반복

 

튜플 인덱싱

순서가 있는 시퀀스 자료형이기에 각 항목에 접근 가능

 

튜플 슬라이싱

리스트와 같이 슬라이싱을 사용하여 부분적인 값 추출 가능

 

튜플 메모리 구조

불변성(immutable)

= 메모리 효율성 : 불변성으로 리스트보다 메모리 사용이 효율적

= 해시 가능 : 불변성으로 인해 원소들이 모두 해시 가능할 경우, 튜플도 해시 가능 (튜플=딕셔너리의 키로 사용 가능)

= 보안 : 데이터의 무결성 유지를 해야 하는 경우 데이터의 변경을 방지

 

튜플 메서드

1. count() : 특정 값이 나타나는 횟수 반환

2. index() : 튜플 내에서 처음으로 나타나는 인덱스의 위치를 반환

 

튜플은 리스트와 비슷한 부분이 많아서 많은 이론을 필요로 하진 않아서 편했습니다.

 

딕셔너리 (Dictionary)

비유로 하자면 사전 같은 자료형 (시퀀스 자료형이 아님)

= 키 (Key)와 그에 해당하는 값 (Value)

쌍의 형태로 정보를 저장하므로 특정 정보를 빠르게 찾거나 접근 가능

딕셔너리는 키를 기준으로 데이터를 찾기 때문에 키는 유일해야 함 = 중복된 키를 가질 수 없음

= 값은 중복이 될 수 있음, 중복된 키를 사용할 경우 그 키에 해당하는 이전값은 사라짐

생성 방법은 중괄호({})를 사용하며 키와 값 사이는 콜론(:)을 사용해 구분하며 쌍의 구분은 쉼표(,)를 사용

 

항목 변경 및 추가 : 항목 값을 변경하려면 해당 키를 이용하여 값을 할당

중첩된 딕셔너리 : 딕셔너리 안에 또 다른 딕셔너리가 들어간 것

 

딕셔너리 메모리 구조

3.10 버전 이하 

= 내부적으로 해시 테이블을 사용, 데이터의 검색, 추가, 삭제를 평균 O(1)의 시간 복잡도로 처리 가능

해시테이블의 시각화

 

 

= 해시 테이블은 버킷(Bucket)을 추가적으로 할당해주어야 하므로 메모리 공간을 약간 더 사용하는 경향 (빠른 검색 시간을 위한 trade-off)

 

딕셔너리 특징

1. 키의 유일성

= 키는 고유함, 중복된 키를 가진 항목을 추가하면 기존의 값을 덮어씀

2. 순서 유지

= 파이썬 3.7부터 딕셔너리 항목 삽입한 순서를 유지함, 내부적으로 이중 연결 리스트를 사용하여 구현 (double linked list)

3. 다양한 데이터 타입

해싱이 가능한(변경 불가능한) 타입이어야 함, 문자열, 숫자, 튜플 등이 키로 사용될 수 있음 (값은 어떤 데이터 타입도 가능)

4. 동적 크기

= 필요에 따라 동적으로 크기 조정, 항목을 추가하거나 삭제할 때 크기에 대한 걱정 필요 없음

5. 효율적인 검색

= 해시 테이블을 기반으로 데이터 검색이 매우 빠름, 키-값 쌍의 형태로 저장하여 관리도 용이함

 

딕셔너리 메서드

1. clear() : 딕셔너리의 모든 키-값 쌍을 삭제

2. copy() : 얕은 복사본을 반환

3. fromkeys() : 시퀀스 자료형을 기반으로 딕셔너리 생성

4. get() : 에러 없이 값을 추출하기 위함, 해당 키가 없을 경우엔 None 반환, 두 번째 인자에 값을 넣어 기본값 반환도 가능

5. itmes() : 키-값 쌍으로 추출할 때 사용, 반환되는 결과는 dict_items 객체 (인덱싱을 하고 싶을 땐 list로 변환해야 함)

+ 키의 존재 여부 확인 : in 연산자 사용

6. keys() : 딕셔너리의 모든 키를 추출할 때 사용, 반환되는 결과는 dict_keys 객체

+ 리스트와 유사하지만 리스트 메서드를 모두 지원하진 않음, 반복문과 함께 사용하여 키를 순회할 순 있음

7. pop() : 주어진 키의 값을 반환하고 해당 키-값 쌍을 딕셔너리에 삭제 (아무것도 없는 값을 pop 하게 되면 Error 출력)

8. popitem() : 딕셔너리의 마지막 키-값 쌍을 반환하고 그 항목을 삭제

9. setdefault() : 주어진 키에 대한 값을 반환, 키가 없으면 기본값 설정 후 반환

10. update() : 기존 딕셔너리에 추가 데이터를 병합하려면 update 메서드 사용

11. values() : 딕셔너리에서 값들만 추출할 때 사용, 반환되는 값은 dict_values 객체

+ 반복문과 함께 사용하여 순회할 수 있음, 리스트로 변환하려면 list() 함수 사용

 

마지막으로 셋에 대해 공부하고 마무리가 됩니다..!

오늘도 이론 브레이크 없어요..! 글이 조금 길어도 복습에 필요한 내용이니 요약하기가 어렵네요 ;u;

 

셋 (Set)

= 자료형은 집합이라 부르며, 리스트나 튜플과 다르게 순서가 없으며 중복된 값도 허용하지 않음

(인덱싱으로 항목에 접근하는 것은 불가능함, 하지만 연산이나 값의 존재 여부 확인은 매우 빠르게 수행됨)

생성 방법은 중괄호({})를 사용하여 안에 쉼표(,)로 구분된 데이터를 넣음

set() 함수를 이용하여 다른 자료형을 집합으로 변환 가능

 

집합 특징

1. 중복을 허용하지 않음

= 수학적 집합의 성질과 일치, 중복된 값을 집합에 추가하려고 하면 그 값은 단 한 번만 저장

2. 순서가 없음

= 리스트나 튜플은 인덱싱이 가능하지만 집합은 인덱싱으로 값을 얻을 수 없음, 특정 값 확인은 가능

+ 특정 값 확인 : in 

3. 가변적 (Mutable)

= 원소의 추가 및 삭제 가능, 하지만 집합 내 원소는 변경 불가능한 데이터만 가능

+ 리스트는 집합의 원소가 될 수 없지만 튜플은 가능

4. 왜 사용할까?

= 중복 제거에 매우 유용, 집합 연산을 사용하여 두 그룹의 유사성이나 차이점도 빠르게 확인 가능

 

집합의 연산

합집합 : 두 집합의 모든 원소를 포함하는 집합 반환

교집합 : 두 집합에 공통으로 포함된 원소만 포함하는 집합 반환

차집합 : 첫 번째 집합의 원소 중 두 번째 집합에 포함되지 않은 연소만을 포함하는 집합 반환

 

집합 메모리 구조

해시 테이블 기반으로 구현

(테이블 내 위치(Hash)를 갖게 되며 이를 통해 빠른 검색 가능)

 

집합 메서드

1. add() : 원소 추가

2. clear() : 모든 원소 제거

3. copy() : 얕은 복사본 반환

4. remove() : 특정 원소 제거, 원소가 집합에 없을 경우 KeyError 발생

5. discard() : remove와 비슷하게 원소 제거 하지만, 해당 원소가 집합에 없어도 Error 발생하지 않음

6. pop() : 값을 지우고 싶을 때 사용

7. difference(others) : 모든 others 집합과의 차집합 반환

8. difference_update(others) : 집합을 others 집합과의 차집합으로 업데이트

9. intersection(others) : 모든 others 집합과의 교집합 반환

10. intersection_update(others) : 집합을 others 집합과의 교집합으로 업데이트

11. isdisjoint(other) : 두 집합이 공통 원소를 가지지 않으면 True 반환

12. issubset(other) : 집합이 others의 부분집합인 경우 True 반환

13. issuperset(other) : 집합이 others 의 상위집합인 경우 True 반환

14. symmetric_difference(other) : 두 개의 집합이 있을 때 공통된 부분을 제외한 나머지 부분을 대칭차집합이라 함

+ (^) 또는 symmetric_difference 함수 사용

15. symmetric_difference_update(other) : 집합을 other와 대칭차집합으로 업데이트

16. union(others) : 모든 others 집합과의 합집합 반환

 

을 끝으로 이론과 코랩 이론 이해를 마무리하였습니다.

이론상으로도 많은 내용을 담고 있고, 또 비슷한 부분이 많아서 복습을 하지 않으면 헷갈릴 것 같네요.

자세한 코드 관련 부분으로는 GitHub에 올려놨습니다.

필요하시다면 참고 하심 될 것 같아요!

728x90
300x250
LIST

'BootCamp > 모두의연구소:오름캠프' 카테고리의 다른 글

24.01.09  (2) 2024.01.09
24.01.08  (4) 2024.01.08
24.01.04  (4) 2024.01.05
24.01.03  (5) 2024.01.03
24.01.02  (0) 2024.01.02