ABC부트캠프 데이터 탐험가 과정

[4일차] ABC 부트캠프 파이썬 기초지식 2

hwibeenjeong 2024. 7. 9. 22:20

기초지식 2

(리스트, 튜플, 딕셔너리, 조건문, 반복문)

 

0. 들어가기 앞서

 리스트, 튜플 딕셔너리는 시퀀스 데이터 타입이다. 여기서 시퀀스는 문자열에도 포함이 되지만, 문자열과 시퀀스 데이터 타입은 차이가 있다. 그 이유를 먼저 알아보자면, 문자열은 기본적으로 수정이 불가능하다. 이 말은 변수와 달리 한 번 문자열이 정해지면 수정할 때 새로운 문자열 변수를 생성하는 방법만 가능하다.

이와 같이 수정이 불가능한 객체들을 Immutable 객체라고 한다. 이와 반대로 앞으로 배울 리스트, 딕셔너리는 Mutable(수정 가능한),  튜플은 Immutable(수정 불가능한) 객체임을 알면 좋을 것 같다.

 

1. 리스트 (List)

 리스트는 다양한 자료형들이 모인 집합을 의미한다. C언어 등에서의 리스트는 동일한 자료형만을 가지고 생성할 수 있었지만, 파이썬의 리스트는 정수형, 실수형, 문자열 등 다양한 자료형들을 리스트로 만들 수 있다.

 

리스트를 생성하는 방법은 두 가지가 있다. 변수에 직접 리스트를 할당하거나, 정해진 문자열 등을 리스트 형태 함수를 통해 리스트화할 수 있다.

list1 = [1, 2, 3, 4]   # 변수에 직접 리스트 할당

word = "hello"
list(word)             # 리스트 형태 함수 사용

 

 리스트는 시퀀스 데이터 타입인 만큼 인덱스와 슬라이싱을 통해 원하는 값들을 불러올 수 있다. 인덱싱과 슬라이싱에 대한 자료는 3일 차 테크노트에 있으니 참고하면 될 것 같다. 위에서 이야기했듯이 리스트는 수정 가능한 Mutable 객체이다. 그렇기 때문에  삽입, 삭제가 가능하다. 다음의 코드를 참고해 보자.

list1 = [1, 2, 3, 4, 5]
list2 = [-1, -2, -3, -4, -5]

#리스트에 값을 추가하는 방법
# 방법 1.  append함수를 사용
list1.append(6)     # 결과 값: list1의 요소는 [1, 2, 3, 4, 5, 6]이 된다.
# 방법 2.  extend함수를 사용
list1.extend(list2) # 결과 값: list1의 요소는 [1, 2, 3, 4, 5, -1, -2, -3, -4, -5]가 된다.
# 방법 3.  insert함수를 사용
list1.insert(5, 6)  # 결과 값: list1의 요소는 [1, 2, 3, 4, 5, 6]이 된다.

# 리스트에서 값을 삭제하는 방법
# 방법 1.  del 예약어를 사용
del list1[3]        # 결과 값: list1의 요소는 [1, 2, 3, 5]가 된다.
# 방법 2.  remove함수를 사용
list.remove(1)      # 결과 값: list1의 요소는 [2, 3, 4, 5]가 된다.

 

리스트에 요소를 추가하는 방법 (형태)

  • append 메서드 사용: append 메서드는 리스트의 가장 마지막 위치에 원하는 요소를  삽입하는 기능을 수행한다.
리스트 이름.append(추가하고자 하는 요소

 

  • extend  메서드 사용: extend 메서드는 리스트와 리스트를 합치는 기능을 수행한다.
리스트 이름.extend(추가하고자 하는 또 다른 리스트)

 

  • insert    메서드 사용: insert 메서드는 리스트의 원하는 위치에 요소를 삽입하는 기능을 수행한다.
리스트 이름.insert(인덱스, 추가하고자 하는 요소)

 

 

리스트에서 요소를 제거하는 방법 (형태)

  • del 예약어 사용: del 리스트[인덱스] 형식을 사용하며, 원하는 위치의 요소를 삭제할 수 있다.
del 리스트 이름[삭제하고자 하는 요소의 인덱스]

 

  • remove 메서드 사용: remove 메서드를 사용하면 원하는 요소를 지정해서, 어느 위치에 있던 삭제가 가능하다.
리스트 이름.remove(삭제하고자 하는 요소)

 

추가로 리스트의 가장 마지막 요소를 가져오는 pop() 메서드와 리스트 간의 덧셈 연산, 곱셈 연산도 가능하다. 덧셈 연산과 곱셈 연산은 문자열에서 사용됐던 것처럼 이어 붙여주고, 반복해 주는 역할을 한다.

 

만약 변수 명을 list로 지정한 적이 있다면 리스트의 형태함수를 사용하지 못할 것이다. 그 이유는 형태함수를 사용할 수 있게 해주는 코드 위에 변수로써 값을 할당했기 때문에 오류가 날 수 있으니 리스트 변수를 생성할 때에는 변수 명을 신경 써야 한다. 

 

마지막으로 리스트 안에 독립적인 리스트를 삽입할 수 있다. 이를 다 차원 리스트라고 한다.

matrix = [ [1, 2, 3],
	   [4, 5, 6],
           [7, 8, 9]]
# 2차원 배열

 

2. Range

Range는 list와 마찬가지로 시퀀스 데이터 타입이다. Range의 역할을 살펴보자.

# 0부터 9까지의 범위 지정
range(0, 10)

range함수는 슬라이싱과 범위를 지정하는 메커니즘이 유사하다. 시작점, 끝점, 단계를 설정하되, 단계가 1이라면 생략이 가능하다. 

 

3. 튜플(Tuple)

 리스트와 유사하지만 튜플은 Immutable 객체이기 때문에 삽입, 삭제, 수정이 불가능하다. 하지만 인덱싱과 슬라이싱은 사용가능하다.

tuple1 = (1, 2, 3)
tuple2 = 1, 2, 3   #다음과 같이 소괄호의 생략이 가능하다.

튜플의 생성은 보편적으로 소괄호로 묶지만, 상황에 따라서는 소괄호를 생략할 수 있다. 튜플은 주로 작은 크기의 데이터를 다루게 되면 사용할 수 있다. 또한, 리스트와 달리 불변 객체(크기가 고정)이기 때문에 한 번 할당된 메모리를 늘리거나 줄일 수 없다. 즉, 가변 객체(크기가 유동적)인 리스트와 달리 여분의 메모리가 필요 없기 때문에 불러오는 속도가 빠르다는 것이다. 하지만, 튜플 내에서의 순서 전환이나, 덧셈 연산과 곱셈 연산은 리스트와 동일하게 지원하고 있다. Immutable 객체이므로 삽입, 삭제, 수정에 관한 메서드는 지원하지 않는다.

 

4. 딕셔너리(Dictionary)

파이썬에서 지원하는 딕셔너리는 해시 테이블 기반의 자료구조이다. 해시 테이블이라고 한다면 키 값을 해시 값으로 변환하고, 이 해시 값을 이용해서 값을 저장 혹은 조회한다. 자료구조에서 해시 테이블의 시간 복잡도는 O(1)이고, 상수 시간이 걸린다는 것을 의미한다.  쉽게 말하면 딕셔너리에서 값을 조회할 때 키 값만 알고 있다면 정말 빠른 속도로 저장된 값을 가져올 수 있다는 것이다. 또한 딕셔너리는 순차적이지 않기 때문에 인덱싱은 가능하지만, 슬라이싱은 불가능하다. 그렇기 때문에 우리가 딕셔너리를 부를 때 맵핑 데이터 타입이라고 한다. 그렇다면 이제 형태와 예시를 알아보자

dict = {"key" : "value", "key" : "value", key" : "value", ...}

위와 같은 형태를 사용해서 딕셔너리를 사용할 수 있다.  딕셔너리의 키들을 모두 조회하는. keys() 메서드와 값들을 모두 조회하는. values() 메서드가 있다. 지금까지 문자열, 리스트, 튜플은 인덱스 값을 통해서 저장된 값을 조회했다면 딕셔너리의 경우 key를 이용해 인덱싱을 할 수 있다. 인덱싱을 하는 방법에는 두 가지가 있다.

dict = {"a" : "A", "b" : "B", "c" : "C"}

# 방법 1.
dict["a"]

# 방법 2.
dict.get("a")

 

 방법 1의 경우 별 다른 메서드를 사용하지 않고 인덱싱을 하는 방법이다. 이 방법의 치명적인 문제점은 만약 딕셔너리 내에 찾고자 하는 키가 없을 시 오류가 발생한다는 점이다. 하지만 방법 2를 사용하게 되면 메서드를 사용해야 하는 번거로움은 있지만 찾고자 하는 키가 없을 시 오류를 반환하는 것이 아닌 지정한 반환 값을 반환해 준다.

dict = {"a" : "A", "b" : "B", "c" : "C"}

dict.get("d", "d라는 키는 존재하지 않습니다.")
# 결과 값: "d라는 키는 존재하지 않습니다"

 

대괄호를 이용한 인덱싱과 get메서드를 이용한 인덱싱을 모두 살펴보았는데 정리하자면, 가장 큰 차이는 예외 처리를 할 수 있느냐 없느냐이다. 대괄호를 이용한 인덱싱에서는 찾고자 하는 키 값이 없을 시 오류를 발생하지만, get메서드를 이용하면 오류가 발생하지 않고, 정해진 문자열 혹은 지정된 문구를 반환하게 된다.

 

5. 조건문 (If)

이제부터 머리가 조금씩 아파올 것이다. 조건문과 반복문 같은 흐름 제어문을 이용하는 데 머리가 아프지 않다면, 코드를 잘못 작성하고 있거나, 효율이 매우 떨어지는 코드일 확률이 크다. 파이썬의 조건문을 살펴보자.

if(참과 거짓으로 구분이 가능한 조건):
    실행 코드 1
    실행 코드 2

 

if문은 "만약 '조건'이 참이라면 '실행 코드'를 실행"과 같은 기능을 수행한다. 한 가지 작업을 처리하는 데에 있어 한 가지의 조건이 있으면 좋겠지만, 이러한 경우는 거의 없을 것이다. 두 가지 이상의 조건을 사용해야 될 땐 'elif'문을 사용한다. 

if(조건 1):
    실행 코드 1
    실행 코드 2
elif(조건 2):
    실행 코드 1
    실행 코드 2
else:
    실행 코드

 

조건 1과는 다른 조건 2부터는 elif(else + if)를 사용하게 되는데, 조건을 모두 따져도 그 밖의 데이터들은 else 문의 실행 코드를 실행하게 된다. 개념만 보면 그렇게 어려울 것 같지는 않을 것이다. 하지만 if문은 중복을 지원하고, 조건에 논리 연산자 및 비교 연산자를 사용할 수 있다는 것이다. 그리고, 무엇보다도 코드를 원하는 방향으로 코딩하기 위해서 조건문에 어떤 조건을 걸어야 하는지 고민하는 순간이 제일 머리 아프지 않을까 싶다. 

 

6. 반복문 (For, While)

반복문은 조건문과 더불어 코드의 흐름을 제어하는 기능을 한다. 파이썬에서 코드를 반복하는 방법에는 두 가지가 있다. for문을 사용하는 방법과 while문을 사용하는 방법이다. 무슨 차이가 있는지 살펴보자.

1.
for 반복 횟수 설정:
    실행 코드
    실행 코드

2.
while 반복 조건:
    실행 코드
    실행 코드

 

반복문의 형태는 for문과 while문으로 나뉘지만, 두 반복문은 반복 횟수를 결정하는 데에 큰 차이가 있다. 먼저 for문을 보게 되면 반복 횟수를 우리가 직접 정해줘야 한다. 프로그래머가 직접 반복 횟수를 지정해주다 보니 유한한 범위를 사용한다. 반복 횟수는 주로 range를 이용해 수열을 만들거나, 리스트와 같은 집합을 이용해 요소를 꺼내오는 등의 기능을 구현하기도 한다. 반대로 while문은 반복 조건을 제시하여 반복을 진행한다. 이 점에서 for문과 큰 차이를 보이는데, 반복 조건이 끝나지 않는 다면 무한 루프(반복)에 빠지게 된다. 무한 루프에 빠지게 되면 프로그램을 강제 종료 시키거나 키보드 인터럽트(Ctrl + c)를 발생시켜 중단시키는 방법이 있다.

while True:
    실행 코드
    실행 코드

 

while문의 조건을 True로 설정할 시 기약 없이 실행 코드를 실행할 뿐이다. 의도해서 무한 루프를 만들었고, 프로그램은 종료해야겠다면 우리는 종료 조건과 break 키워드를 이용해 무한 루프를 빠져나올 수 있다. break 키워드의 기능은 다음과 같다.

break 키워드와 가장 가까운 반복문을 종료한다.

 

break 키워드를 이용하면 당장 가장 가까운 반복문을 종료하고 반복문의 바깥쪽의 코드를 실행하게 된다. break 키워드와 유사한 기능을 하는 키워드가 한 가지 더 있다. 바로 continue 키워드. continue 키워드의 기능은 다음과 같다.

조건을 만족하면 해당 반복의 나머지 코드를 건너뛰고 루프의 다음 반복으로 넘어간다.

 

continue 키워드를 이용하면 실행하던 반복의 나모지 코드를 건너뛰고 다음 반복을 실행하게 된다. 즉, break 키워드를 이용하면 반복 횟수가 남아 있더라도 바로 반복문을 탈출해 버리지만, continue 키워드를 이용하면 현재 반복은 중단하더라도 남은 반복은 계속 진행한다는 차이가 있다. 백문이 불여일견. 예시를 같이 보면 이해하기 훨씬 쉬울 것이다.

for i in range(0, 10):
	if i % 3 == 0:
    	print(i)
        break

# 결과 값: 3

for i in range(0, 10):
	if i % 3 == 0:
    	print(i)
        continue

# 결과 값: 3, 6, 9

 

지금까지 반복문과 break, continue 키워드를 살펴보았다.

 

7. Match

파이썬의 match구문은 C언어의 switch구문과 동일하다고 보면 된다. if와 elif, else는 조건을 사용해 실행할 코드를 정한다면, match 구문은 정해진 값과 비교하여 원하는 실행 코드를 실행한다고 보면 된다. 사용법은 간단하다. 

match 비교 대상
    case 비교 값:
        실행 코드
    case 비교 값:
        실행 코드
    case 비교 값:
        실행 코드
    case 비교 값:
        실행 코드

match 다음에 비교할 대상을 작성해 주고, case 다음에는 비교 값을 적어주면 된다. 첫 번째 case에서 비교 대상에 부합하는 값이라면 실행 코드를 실행시키지만, 만약 첫 번째 case의 비교 값과 비교 대상이 일치하지 않는다면 다음 case로 넘어간다. match문은 파이썬에 도입된 지 오래되지 않았고, match문 대신 조건문, 반복문을 이용하는 경우가 많기 때문에 이런 것도 있구나 하고 알고 넘어가는 것도 괜찮을 것 같다.

 

 

코드의 흐름제어까지 배웠으니 기본적인 문법은 거의 다 배운 것 같다.
지금까지는 배웠던 지식들에 대해 점검하는 시간이었다면 앞으로 배울 내용들은 새로운 내용들일 것 같아서
설렌다.