k-mozzi 2021. 10. 2. 18:31
반응형
Preface

 

이번 장에선 지난 포스팅에 이어 배열을 공부했다.

 

내용 면에선 크게 어려운 부분이 없었지만, 이를 알고리즘을 통해 실제 코드로 구현하는 실습 과정이 생각보다 복잡했다.

 

코드를 한 줄 한 줄 읽어보면 분명 이해는 할 수 있지만, 막상 풀이 과정을 보지 않고 혼자 해결하려 하면 어떻게 구현해야 할 것인지 감이 오지 않았다.

 

다시 말해 개별적인 함수의 사용법은 어느정도 숙지했지만, 이 함수들을 사용하여 문제를 해결할 방법이 잘 떠오르지 않는다.

 

당분간은 특정 문제가 주어졌을 때 이를 해결하기 위해 어떤 접근 방법을 취해야 할 것인지에 초점을 맞춰 차근차근 코드를 작성하는 연습을 할 계획이다.

 

소프트웨어 공학에서 공부했던 것처럼 추상화 단계를 점차 낮추며 코드를 작성하자! 


 

1. 배열이란?

 

 

- 스캔(주사, 트래버스) : 배열 원소를 하나씩 차례로 주목하여 살펴보는 방식

 

 

- 배열의 최댓값을 구하는 코드

def max_of(a):
    maximum = a[0]
    for i in range(1, len(a)):
        if a[i] > maximum:
            maximum = a[i]
    return maximum


if __name__ == '__main__':
    print('배열의 최댓값을 구합니다.')
    num = int(input('원소 수를 입력하세요: '))
    x = [None] * num  # 원소 수가 num 인 리스트를 생성

    for i in range(num):
        x[i] = int(input(f'x[{i}]값을 입력하세요: '))

    print(x)
    print(f'최댓값은 {max_of(x)}입니다.')

 

 

- Any : 제약이 없는 임의의 자료형

 

 

- Sequence(시퀀스형) : 데이터를 순서대로 하나씩 나열하여 나타낸 데이터 구조

→ 리스트형, 바이트 배열형, 문자열형, 튜플형, 바이트열형 등

 

 

- 어노테이션(annotation, 주석 달기) : 강제성이 없으며, 코드에 영향을 주지 않음

from typing import Any, Sequence


def max_of(a: Sequence) -> Any:

 

 

- 모듈 : 하나의 스크립트 프로그램

1) 확장자를 포함하지 않는 파일의 이름 자체를 모듈 이름으로 한다.

2) 스크립트 프로그램이 직접 실행될 때 변수 __ name__은 '__main__'이다.

3) 스크립트 프로그램이 임포트 될 때 변수 _ name__은 원래의 모듈 이름이다.

 

 

- 리터럴(고정된 값)이 아니면 원소 값이 같아도 실체는 다르다.

list1 = [1, 2, 3, 4]
list2 = list1[:]
list2[1] = 8
print(list1)
print(list2)

 

 

- enmerate( ) 함수 사용

x = ['a', 'b', 'c']

for i, name in enumerate(x, 1):
    print(f'x[{i}] = {name}')
# 몇 번째부터 시작할 지 정할 수 있음

 

 

- 이터레이터(iterator)는 데이터의 나열을 표현하는 객체이다.

it = iter(range(3))
print(next(it))
print(next(it))
print(next(it))
# iter() 는 그 객체에 대한 이터레이터(반복자)를 반환한다.
# next() 함수에 이터레이터를 전달하면 원소를 순차적으로 꺼낸다.
# 꺼낼 원소가 더 이상 없을 땐 StopIteration 으로 예외를 발생시킨다.

 

 

- 의사 코드(pseudo code) : 컴퓨터에서 바로 실행할 순 없지만, 알고리즘을 간단하고 분명하게 나타내는 코드

 

 

- 0~9까지의 숫자 10개와 A~Z까지의 알파벳 26개를 사용하여 36진수까지 표현할 수 있다.

 

 

- 기수와 서수

1) 기수 : 수를 나타내는 데 기초가 되는 수

→ 0, 1, 2, 3...

2) 서수 : 사물의 순서를 나타내는 수

→ 첫째, 둘째, 셋째...

 

 

- 진수의 종류

1) 10진수(decimal) : 0, 1, 2, 3, 4, 5, 6, 7, 8, 9의 숫자를 사용

2) 8진수(octal) : 0, 1, 2, 3, 4, 5, 6, 7의 숫자를 사용

3) 16진수(hexadecimal) : 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F의 숫자를 사용

 

 

- 10진수를 2~36진수로 변환하는 코드

# 10진수 값을 입력받아 2~36진수로 변환하여 출력

def card_conv(x: int, r: int) -> str:
    d = ''
    dchar = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'

    while x > 0:
        d += dchar[x % r]
        x //= r
    return d[::-1]


if __name__ == '__main__':
    print('10진수를 n진수로 변환합니다.')

    while True:
        while True:
            no = int(input('변환할 값으로 음이 아닌 정수를 입력하세요.: '))
            if no > 0:
                break
        while True:
            cd = int(input('어떤 진수로 변환할까요?: '))
            if cd <= 2 <= 36:
                break

        print(f'{cd}진수로는 {card_conv(no, cd)}입니다.')

        retry = input('한 번 더 변환할까요?(Y: 예 / N: 아니요): ')
        if retry in {'N', 'n'}:
            break

 

 

- 1000이하의 소수를 나열하는 코드

counter = 0
ptr = 0
prime = [None] * 500

prime[ptr] = 2
ptr += 1

for n in range(3, 1001, 2):
    for i in range(1, ptr):
        counter += 1
        if n % prime[i] == 0:
            break
    else:
        prime[ptr] = n
        ptr += 1

for i in range(ptr):
    print(prime[i])
print(f'나눗셈을 실행한 횟수: {counter}')

 

 

- 복사

1) 얕은 복사 : 리스트 안의 모든 원소가 참조하는 곳까지 복사

2) 깊은 복사 : 구성 원소 수준으로 복사

import copy


x = [[1, 2, 3], [4, 5, 6]]
y = x.copy()  # 얕은 복사
x[0][1] = 9
print(x)
print(y)


a = [[1, 2, 3], [4, 5, 6]]
b = copy.deepcopy(a)  # 깊은 복사
a[0][1] = 9
print(a)
print(b)

 

728x90
반응형