본문 바로가기

자료구조

파이썬

1. 변수(variable)

■ 변수는 데이터(자료)를 담는 공간이다.

■ 어떤 값을 변수로 정의하여 사용하는 것은 간단하지만, 변수의 동작 원리는 약간 복잡하다.

■ 먼저 리터럴(literal)이 무엇인지 알아야 한다.

리터럴은 예를 들어 1, 1.2, "apple"같이 그 자체로 의미하는 것을 말하는데, 변수와 달리 데이터가 저장된 공간을 가리키는 이름을 가지지 않는다.

■ 1같이 아라비아 숫자로 표현되는 것을 정수형 리터럴, 1.2는 실수형 리터럴, "apple"은 문자열 리터럴이라 한다. 

즉, 리터럴은 그 형태에 따라 자료형이 결정되는 것이다.

■ 예를 들어 num = 10, name = "apple"이 있다면 num = 10은 변수 num이 만들어지고 변수 num이 리터럴 10에 의해 만들어진 정수 객체를 참조하는 것이다. 즉, 정수 객체를 생성하고 변수 num이 정수 객체를 참조하는 것이다.

name = "apple"은 문자열 객체를 생성하고 변수 name이 이를 참조하는 것이다. 이를 그림으로 표현하면 다음과 같다.

■ 이미 정의한 num이란 변수가 있지만, num = 1.2를 실행하면 변수 num은 새로운 실수 객체(1.2)를 참조하게 되어서 기존의 객체 10을 참조하는 변수가 없어진 것이므로 객체 10은 자동으로 삭제된다.

만약, fruits = name이 실행되면 name이 참조하는 객체("apple")는 새로운 변수 fruits가 같이 참조하게 된다.

■ 객체 None을 사용하면, 변수가 아무런 객체도 참조하지 않게 만들 수 있다. 예를 들어 num2 = None이면 변수 num2는 null을 참조하게 된다.

 

2. 분기(branching)

파이썬에서는 분기를 위해 if 문을 제공하며, if - else문, if - elif - else 문으로 다중 분기를 수행할 수 있다.

# 분기
if num % 2 == 0:
    print(num)
    
# 다중 분기 if - else
if num % 2 == 0:
    print(num)
else:
    print('2')
    
# 다중 분기 if - elif - else
if num % 2 == 0:
    print(num)
elif num % 3 == 0:
    print(num)
else:
    print('2' and '3')

 

3. 반복(looping)

■ 파이썬에서 반복을 위해 while 문, for 문을 지원하며, 루프를 빠져나오거나 계속 루프를 진행하기 위해 break, continue도 지원한다.

■ 일반적으로 for 문을 수행할 때, 반복 횟수를 설정하기 위해 range(start, end, step) 함수를 사용하지만, range( )를 사용하지 않고 컬렉션 자료형(문자열, 리스트, 튜플, 딕셔너리, 집합)을 이용해 for 문을 수행할 수 있다.

for i in 'python': # 문자열
    print(i, end = "")

for i in [1, 2, 3, 4, 5]: # 리스트
    print(i, end = "")

for i in (1, 2, 3, 4, 5): # 튜플
    print(i, end = "")
    
for i in {'a':97, 'b':98, 'c':99}: # 딕셔너리
    print(i)
    
for key, value in enumerate({'a':97, 'b':98, 'c':99}): # 딕셔너리
    print(key, value)
    
for i in set([1, 2, 3, 4, 5]): # 집합
    print(i, end = "")

■ 문자열, 리스트 튜플은 시퀀스 자료구조이므로 순서대로 출력되지만, 딕셔너리와 튜플은 선형 자료구조가 아니므로 출력 순서가 랜덤이지만, 모든 항목들을 반드시 한 번씩 출력되는 것을 볼 수 있다.

 

리스트 (tistory.com)

 

리스트

1. 리스트리스트는 항목(item)을 저장하는 컨테이너의 역할을 한다. 이 컨테이너 안에서 항목들은 순서를 가지고 저장된다.■ 리스트는 대괄호를 이용해 만들 수 있다. 이때 리스트 안에 저장되는

hyeon-jae.tistory.com

튜플, 딕셔너리, 세트, 문자열 (tistory.com)

 

튜플, 딕셔너리, 세트, 문자열

1. 튜플■ 튜플(tuple)은 리스트와 다르게 항목(또는 요소)값의 변경이 불가능하다. 이 점만 제외하면 리스트와 동일하다. ■ 튜플은 기본적으로 ()으로 생성할 수 있으며, 이 외에도 다양한 방법으

hyeon-jae.tistory.com

 

4. 사용자 정의 함수

■ 함수는 def 키워드를 이용해 다음과 같이 정의한다.

def 함수_이름(매개변수1, 매개변수2, ...):

■ def로 정의하는 부분을 '함수 헤더', 안 쪽의 실행문을 '함수의 몸체'라 한다.

■ 정의한 함수는 호출 시 실행되며 이때, 함수에 필요한 정보를 전달하는데 이러한 값을 인수(argument)라 한다.

■ 전달된 인수는 함수 헤더의 매개변수(parameter)로 전달되고, 함수의 몸체에서 결과를 계산해서 결과를 호출한 위치로 되돌려준다.

■ 예를 들어 다음과 같이 작동된다.

■ 여러 개의 결과를 반환하게 만들 수도 있다.

def sub(num_list):
    result = 0
    count = 0
    for n in num_list:
        result -= n
        count += 1
    return result, count
    
num = [1, 2, 3, 4, 5]
a = sub(num)
sub_count, sub_result = a

print(sub_count, sub_result)
```#결과#```
-15 5
````````````

■ 매개변수에 디폴트 인수(default argument)를 지정한다면, 함수 호출시 인수가 주어지면 그 인수를 사용하고, 인수를 생략할 경우 디폴트 인수의 값을 사용한다.

def sub(start, end, step = 3):
    result = 0
    for i in range(start, end, step):
        result -= i
    return result

print(sub(1, 10))
print(sub(1, 10, 1))

- sub(1, 10)처럼 step의 값을 입력하지 않으면, sub 함수의 디폴트 매개변수 step = 3으로 수행되고, sub(1, 10, 1)처럼 step의 값을 지정하면, 지정한 값인 step = 1로 수행된다.

■ 함수 호출시 함수의 매개변수 이름에 값을 지정해서 함수를 호출할 경우 키워드 인수(keyword argument)를 사용한 것이다. 키워드 인수를 사용할 경우, 다음과 같이 인수의 순서를 바꿔서 함수를 호출해도 무방하다.

sub(step = 1, start = 1, end = 10) # 키워드 인수 사용
```#결과#```
-45
````````````

■ 함수, 클래스의 메소드 안에서 생성한 변수는 지역 변수(local variable)라 하며, 그 안에서만 사용할 수 있다.

반면, 전역 변수(global variable)는 함수나 클래스 외부에서 생성된 변수로 어디에서나 사용할 수 있으며, global 키워드를 사용하여 함수 내에서 전역 변수를 지정할 수 있다.

cf) 인스턴스 변수(instance variable): 클래스의 멤버로 생성된 변수로, 클래스 내의 다른 함수들에서 사용할 수 있다.

 

5. 모듈

파이썬에는 numpy, pandas, tensorflow, keras, pytorch 등 많은 모듈들을 'import'하여 사용할 수 있다.

■ 모듈의 장점은 어떤 큰 프로그램을 작성할 때, 한 파일 내에 모든 코드를 작성하지 않고 여러 파일에 나누어 작성하고 실행할 수 있다는 점이다.

■ 예를 들어 다음과 같은 사용자 정의 함수를 각각의 소스 파일에 .py 확장자로 저장해 보자.

위의 파일들(cal_add.py, cal_sub.py)을 import 키워드를 이용해 새로운 파일에 불러와서 모듈에 있는 함수를 사용할 수 있다.

import cal_sub
import cal_add

print(cal_sub.sub(1, 10, 1))
print(cal_add.add(1, 10, 1))
```#결과#```
-45
45
````````````

■ 이렇게 불러온 모듈을 사용하려면, 항상 모듈 이름을 통해 호출해야 한다.

편리하게 사용하려면 이름 공간(name space)을 이용하면 된다.

■ 파이썬의 모든 모듈들은 자신의 이름 공간을 가지며, 이름 공간 안에서 모든 식별자를 사용할 수 있다.

■ 예를 들어 math 모듈의 sqrt 함수를 사용하려면 다음과 같이 사용할 식별자 sqrt가 어떤 모듈에 속하는지 명시하여 사용해야 한다.

import math
math.sqrt(16)

■ 만약, 모듈의 모든 식별자를 사용하고 싶으면, 다음과 같이 '*'을 사용하면 된다.

from math import *
from cal_sub import *
from cal_add import *

print(sub(1, 5, 1))
print(add(10, 15, 3))
print(sqrt(16))
print(pow(2, 6))
```#결과#```
-10
23
4.0
64.0
`````````````

 

6. 클래스

클래스는 객체를 찍어내는 틀이고, 객체는 자료를 저장하는 요소이다.

클래스 (tistory.com)

 

클래스

1. 객체와 클래스■ 파이썬에서는 모든 것이 객체(object)로 구현된다. 여기서 객체란 함수와 변수를 하나의 단위로 묶을 수 있는 방법이다.■ 예를 들어 자동차는 브랜드, 모델, 색상, 연식, 가격

hyeon-jae.tistory.com

■ 파이썬의 모든 자료는 클래스로부터 만들어진 객체이다. 정수, 실수도 클래스로 되어 있다.

■ 예를 들어 'num = 1' 문장은 리터럴 1에 따라 정수 클래스의 객체가 만들어지고 변수 num이 만들어져서 이 정수 객체를 참조하는 것이다.

클래스는 속성을 나타내는 멤버 변수와 동작을 나타내는 메소드(<=> 멤버 함수)로 이루어진다.

■ 예를 들어 자동차의 색과 무게 그리고 속도를 클래스로 구현하면, 자동차의 속성인 색, 무게가 멤버 변수, 자동차는 속도를 올리가나 낮출 수 있으므로 이 기능은 메소드(멤버 함수)가 된다.

class Car:
    def __init__(self, color, weight, speed = 0):
        self.color = color
        self.weight = weight
        self.speed = speed
        
    def SpeedUp(self):
        self.speed += 10
        
    def SpeedDown(self):
        self.speed -= 10
        
blue_car = Car('blue', 2)
blue_car.SpeedUp()
blue_car.SpeedUp()
print(blue_car.color, blue_car.weight, blue_car.speed)
```#결과#```
blue 2 20
````````````

■ 이때, 사용된 __init__은 생성자 메소드로 객체가 생성될 때 마다 자동으로 호출되는 함수이다. 예를 들어 Car 클래스 생성자 메소드의 매개변수 중 speed = 0은 새로운 자동차, 즉 새로운 객체가 생성될 때 마다 생성자 메소드가 호출되어 새로운 객체의 speed = 0으로 초기화된다. color, weight도 마찬가지이다.

- blue_car = Car('blue', 2)를 호출하면, def __init__(self, color, weight, speed = 0)에서 self는 호출한 객체인 blue_car이며, color는 blue, weight는 2, speed는 디폴트 인수 0으로 지정된다.

- 이 상태에서 SpeedUp( ) 메소드를 두 번 실행했기 때문에 speed는 10, 20이 되는 것이다.

- 만약 인스턴스 변수의 값을 클래스 외부에서 접근하여 변경하고 싶으면 다음과 같이 변경할 수 있다.

blue_car.color = 'light blue'
print(blue_car.color)
```#결과#```
light blue
````````````

 

■ 파이썬에서 +, -. *, /, <, <= 등의 연산자를 적용할 수 있는 특수 메소드와 클래스로부터 생성한 객체의 내용을 출력하는 __str__( ) 메소드를 지원한다.

클래스 (tistory.com)

 

클래스

1. 객체와 클래스■ 파이썬에서는 모든 것이 객체(object)로 구현된다. 여기서 객체란 함수와 변수를 하나의 단위로 묶을 수 있는 방법이다.■ 예를 들어 자동차는 브랜드, 모델, 색상, 연식, 가격

hyeon-jae.tistory.com

 

7. 상속(inheritance)

■ 상속은 코드 재사용 측면에서 효과적인 방법으로, 기존에 정의한 클래스로부터 새로운 클래스를 만드는 방법이다.

■ 상속해주는 클래스를 기본(base) 클래스 또는 부모 클래스라 하고, 상속받는 클래스를 파생(derived) 클래스 또는 자식 클래스라고 한다. 즉, 상속해주는 클래스와 상속받는 클래스는 '자식 is - a 부모' 관계를 갖는다.

■ 예를 들어 버스, 트럭, 소형차 등은 모두 '자동차'라는 뿌리에서 파생된 특화된 버전의 자동차이다. 즉, 부모 - 자식의 관계로 볼 수 있으며 이들을 Car 클래스로부터 상속받는 다면, 상속 관계는 다음과 같이 표현할 수 있다.

상속 계층 관계

■ 예를 들어 Car 클래스로부터 상속받는 Bus 클래스를 생성하려면 먼저, 다음과 같이 Bus 클래스를 정의해야 한다.

class Bus(Car):

■ 그 다음으로 생성자 함수를 구현해야 한다. 단, Car 클래스의 변수를 그대로 물려받고 싶으면 생성자 메소드 안에서 변수를 다시 정의하지 않고, 다음과 같이 super( ) 함수를 이용한다.

- 만약, 부모 클래스의 변수외에 새로운 변수를 추가하고 싶다면 Bus 클래스 (생성자 메소드) 내에서 새로운 인스턴스 변수 또는 클래스 변수를 정의하면 된다. 메소드도 마찬가지이다.

class Bus(Car):
    car_size = 'big'
    
    def __init__(self, color, weight, speed = 0, power = True):
        super().__init__(color, weight, speed) # 부모 클래스의 생성자 호출
        self.size = Bus.car_size
        self.power = power
    
    def SpeedDown(self):
        if self.power:
            super().SpeedUp() # power = True이면 부모 클래스의 SpeedUp 메소드 호출
        else:
            self.speed *= 0
    
    def __str__(self):
        return f'color: {self.color}, weight: {self.weight}, speed: {self.speed}, size: {self.size}, power: {self.power}'

green_bus = Bus('green', 10, power = True) # 버스 시동 on
green_bus.SpeedUp()
print(green_bus)
```#결과#```
color: green, weight: 10, speed: 10, size: big, power: True
````````````

green_bus.SpeedDown()
print(green_bus)
```#결과#```
color: green, weight: 10, speed: 20, size: big, power: True
````````````

green_bus.power = False # 버스 시동 off
green_bus.SpeedDown()
print(green_bus)
```#결과#```
color: green, weight: 10, speed: 0, size: big, power: False
````````````

-  SpeedDown( ) 메소드는 부모 클래스에 정의되어 있는 메소드이지만, 자식 클래스에서 해당 메소드의 내용을 변경하여 다시 재정의하였다. 이를 메소드 오버라이딩이라 한다.

■ 메소드 오버라이딩은 동일한 메소드 이름으로 어떤 기능을 다시 정의할 때 활용되며, 중복되는 기능을 자식 클래스에서 다시 만들지 않아도 되므로 불필요한 중복을 줄여준다.

상속 (tistory.com)

 

상속

1. 상속■ 상속은 기존에 정의된 클래스로부터 변수와 메소드를 상속받아 새로운 클래스를 만드는 방법이다.■ 필요하다면, 자식 클래스에서 상속받은 메소드를 변경하거나, 새로운 변수나 메

hyeon-jae.tistory.com

 

'자료구조' 카테고리의 다른 글

큐(Queue) (2)  (0) 2024.09.20
큐(Queue)  (0) 2024.09.18
스택(Stack)  (0) 2024.09.10
리스트(list)  (0) 2024.09.06
자료구조와 알고리즘  (0) 2024.08.28