프로그래밍 기초

Chapter.1 프로그래밍 기초(6)

devjjun 2026. 3. 24. 20:56

TIL(Today I Learned)


1️⃣Python 특강 

Numpy

  • NumPy는 Numerical Python의 줄임말로, 파이썬에서 산술 계산을 위한 가장 중요한 패키지 중 하나입니다.
  • NumPy의 핵심 기능 중 하나는 ndarray라고 하는 N차원의 배열 객체인데 파이썬에서 할 수 있는 대규모 데이터 집합을 담을 수 있는 빠르고 유연한 자료구조입니다.
import numpy as np

a = np.array([1, 2, 3])
print(a, type(a))

# Output
# [1 2 3] <class 'numpy.ndarray'>

 


Array(배열) 생성하기

 

NumPy 배열은 모두 같은 유형의 값이며 음수가 아닌 정수의 튜플로 인덱싱됩니다. 차원의 수는 배열의 랭크, 배열의 shape은 각 차원별 배열 크기의 튜플, 중첩 된 파이썬 리스트로부터 NumPy 배열을 초기화 할 수 있고 대괄호를 사용하여 요소에 접근 할 수 있다.

  • np.array(): 기본적으로 배열의 복사본을 생성합니다.
  • np.asarray(): 배열의 복사본을 생성하지 않고, 가능한 경우에는 입력 배열의 뷰(view)를 반환합니다. 즉, 입력 배열과 반환된 배열이 메모리를 공유할 수 있습니다.
a = np.array([1, 2, 3])
print(a)
print(type(a), a.ndim, a.shape, a.dtype)

# Output
# [1 2 3]
# <class 'numpy.ndarray'> 1 (3,) int64
  • np.zeros(), np.ones(), np.full(), np.empty()
a = np.zeros((3,4))
print(a)

# Ouput
# [[0. 0. 0. 0.]
#  [0. 0. 0. 0.]
#  [0. 0. 0. 0.]]
b = np.ones((5,2))
print(b)

# Output
# [[1. 1.]
#  [1. 1.]
#  [1. 1.]
#  [1. 1.]
#  [1. 1.]]
c = np.full((2,3), 3)
print(c)

# Output
# [[3 3 3]
#  [3 3 3]]
d = np.empty((3,3))
print(d)

# Output
# [[4.94484549e-315 0.00000000e+000 1.26071060e-076]
#  [3.05448293e-028 2.21257720e-052 5.74015544e+180]
#  [1.94919988e-153 6.79764374e-310 1.34385856e-321]]

 

  • *_like()
a = np.zeros((2,2))

e = np.zeros_like(a)
f = np.ones_like(a)
g = np.full_like(a, 2)
h = np.empty_like(a)
print(e)
print(f)
print(g)
print(h)

# Output
# [[0. 0.]
#  [0. 0.]]
# [[1. 1.]
#  [1. 1.]]
# [[2. 2.]
#  [2. 2.]]
# [[ 4.94493398e-315  0.00000000e+000]
#  [-2.01326891e-063  2.26172101e-313]]
  • np.random
구분 np.random.rand() np.random.randn() np.random.randint()
분포 균일 분포 (Uniform Distribution) 표준 정규 분포 (Standard Normal Distribution) 이산 균일 분포 (Discrete Uniform Distribution)
값의 범위 0이상 1 미만 (즉, [0.0, 1.0)) 실수 전체 (평균 0, 표준편차 1) [low, high) low 이상, high 미만의 정수 난수
인수 방식 생성할 배열의 차원 수를 인수로 받음 (rand(d1, d2, d3, ...)) 생성할 배열의 차원 수를 인수로 받음 (randn(d1, d2, d3, ...)) randint(low, high=None, size=None)

Array 연산

1. 기본 연산 (Element-wise)

a = np.array([1,2,3])
b = np.array([4,5,6])

# 덧셈
print(a + b)  # [5 7 9]

# 뺄셈
print(a - b)  # [-3 -3 -3]

# 곱셈
print(a * b)  # [4 10 18]

# 나눗셈
print(a / b)  # [0.25 0.4 0.5]

# 거듭제곱
print(a ** 2)  # [1 4 9]

 

2.집계 연산

arr = np.array([1,2,3,4])

print(np.sum(arr))       # 합계 → 10
print(np.mean(arr))      # 평균 → 2.5
print(np.max(arr))       # 최대값 → 4
print(np.min(arr))       # 최소값 → 1
print(np.cumsum(arr))    # 누적합 → [1 3 6 10]

 

3.배열 검색/조건 연산

arr = np.array([1,2,3,4,5])

# 조건 필터링
print(arr[arr > 3])       # [4 5]

# 특정 값 위치 찾기
print(np.where(arr == 3)) # (array([2]),)

# 정렬
print(np.sort(arr))       # [1 2 3 4 5]

 

4. 벡터/행렬 연산 

A = np.array([[1,2],[3,4]])
B = np.array([[5,6],[7,8]])

# 행렬 곱
print(np.dot(A, B))
# [[19 22]
#  [43 50]]

# 전치
print(A.T)
# [[1 3]
#  [2 4]]

# 역행렬
print(np.linalg.inv(A))
# [[-2.   1. ]
#  [ 1.5 -0.5]]

# 행렬식
print(np.linalg.det(A))  # -2.0

2️⃣Python 알고리즘 핵심 문제

문제1

  • 문제 설명
    두 수를 입력받아 두 수의 최대공약수와 최소공배수를 반환하는 함수, solution을 완성해 보세요. 배열의 맨 앞에 최대공약수, 그다음 최소공배수를 넣어 반환하면 됩니다. 예를 들어 두 수 3, 12의 최대공약수는 3, 최소공배수는 12이므로 solution(3, 12)는 [3, 12]를 반환해야 합니다.
  • 제한 사항
    두 수는 1이상 1000000이하의 자연수입니다.
  • 입출력 예

  • 문제 접근
    오랜시간 고민 끝에 구글링을 통해 유클리드 호제법이란걸 알게 되었습니다. 두 수 n과 m에 대한 최대공약수를 구할 함수를 만들고 결과 함수에 호제법을 적용하여 최소공배수를 구하는 방식을 채택하였습니다
  • 코드
def max_digit(n, m):
    while m:
        n,m=m,n%m
    return n

def solution(n, m):
    maxi = max_digit(n,m)
    mini = (n*m) / maxi
    return [maxi,mini]
  • 주요문법

 

- 최대공약수 (GCD)

gcd(a, b) = gcd(b, a % b)

  • b가 0이 될 때까지 반복
  • 마지막 a가 최대공약수

- 최소공배수 (LCM)

lcm(a, b) = (a × b) ÷ gcd(a, b)


문제2

  • 문제 설명
    자연수 n이 매개변수로 주어집니다. n을 3진법 상에서 앞뒤로 뒤집은 후, 이를 다시 10진법으로 표현한 수를 return 하도록 solution 함수를 완성해주세요.
  • 제한 사항
    n은 1 이상 100,000,000 이하인 자연수입니다.
  • 입출력 예

  • 문제 접근
    10진법 자연수 n에 대하여 몫을 3으로 나누는 것을 반복하며 나머지를 문자열에 대입하면 3진법으로 구현이 가능하다. 또한 구현된 3진수를 앞 뒤를 뒤집어 자릿수 별 3의 자릿수 제곱을 곱하여 더하면 10진법으로 구현 가능할 것이다.
  • 코드
def to_3rd(n):
    if n == 0:
        return "0"
    result = ""
    while n > 0:
        digit = n % 3
        n = n // 3
        result += str(digit) 
    return result 

def solution(n):
    result = 0
    for i, digit in enumerate(reversed(to_3rd(n))):
        result += int(digit) * (3**i)
    return result
  • 주요 문법

- enumerate()

  • enumerate()는 반복문에서 인덱스와 값을 동시에 꺼낼 수 있게 해주는 함수
fruits = ['apple', 'banana', 'cherry']

for i, fruit in enumerate(fruits):
    print(i, fruit)

- 10진수 → 3진수 변환

10 ÷ 3 = 3 ... 1
3 ÷ 3 = 1 ... 0
1 ÷ 3 = 0 ... 1

- 3진수 → 10진수 변환

1 × 3² = 9
0 × 3¹ = 0
1 × 3⁰ = 1

💡 느낀점

다양한 알고리즘 문제를 풀며 유클리드 호제법이나 3진수와 10진수 사이의 계산 등 모르는 부분을 학습할 수 있었습니다. 공식을 공부하고 패턴을 알아도 이를 실제 문제에 적용하여 올바른 결과를 도출하는 것이 더욱 어렵게 다가왔습니다. 문제에 대해 깊게 고민하고 현업에서 사용되는 패턴들을 학습할 예정입니다.