so woon!

python_20일차 본문

Python/개념정리

python_20일차

xowoony 2022. 9. 5. 21:43

학습일 : 2022. 09. 05

1. 선택정렬 01

### 배열에서 최솟값의 위치를 찾는 함수 ###
def findMinIdx(ary):
    minIdx = 0    #배열의 0번째 값을 현재 최솟값 위치로 지정
    for i in range(1, len(ary)):     #배열의 1번째 인덱스 값부터 마지막까지 반복
        if ary[minIdx] > ary[i]:       #배열의 i번째 값과 현재 최솟값을 비교해서
            minIdx = i              #i번째 값이 더 작으면 i를 현재 최솟값 위치로 지정
    return minIdx   #찾아낸 배열의 최솟값 위치를 반환

testAry = [55, 88, 33, 77]
minPos = findMinIdx(testAry)
print('최솟값 -->', testAry[minPos])

=============실행결과=============
최솟값 --> 33

 

 

2. 선택정렬 02

### 선택정렬의 구현 ###
def findMinIdx(ary):
    minIdx = 0    #배열의 0번째 값을 현재 최솟값 위치로 지정
    for i in range(1, len(ary)):     #배열의 1번째 인덱스 값부터 마지막까지 반복
        if ary[minIdx] > ary[i]:       #배열의 i번째 값과 현재 최솟값을 비교해서
            minIdx = i              #i번째 값이 더 작으면 i를 현재 최솟값 위치로 지정
    return minIdx   #찾아낸 배열의 최솟값 위치를 반환

before = [188, 162, 168, 120, 50, 150, 177, 105]
after = []


print('정렬 전 -->', before)
for _ in range(len(before)):    #배열의 크기만큼 반복
    minPos = findMinIdx(before)   #정렬 전 배열에서 최솟값의 위치를 찾고
    after.append(before[minPos])    #정렬 후 배열의 맨 뒤에 추가
    #정렬 후 배열에 넣은 값을 정렬 전 배열에서 제거
    #이제 정렬 전 배열에는 가장 작은 값을 제외한 나머지 데이터만 남는다.
    del(before[minPos])
print('정렬 후 -->', after)

=============실행결과=============
정렬 전 --> [188, 162, 168, 120, 50, 150, 177, 105]
정렬 후 --> [50, 105, 120, 150, 162, 168, 177, 188]

 

 

3. 선택정렬 03

### 개선된 선택 정렬 ###
import random

def selectionSort(ary):
    n = len(ary)        #배열의 길이
    for i in range(0, n-1):
        minIdx = i
        for k in range(i+1, n):
            if ary[minIdx] > ary[k]:
                minIdx = k
        ary[i], ary[minIdx] = ary[minIdx], ary[i] #0번째 값과 찾은 최솟값을 교환 #맞교환
    return ary


dataAry = [random.randint(1, 100) for _ in range(8)]

print('정렬 전 -->', dataAry)
dataAry = selectionSort(dataAry)
print('정렬 후 -->', dataAry)

=============실행결과=============
정렬 전 --> [48, 37, 53, 6, 48, 92, 84, 18]
정렬 후 --> [6, 18, 37, 48, 48, 53, 84, 92]

 

 

 

4. 삽입 정렬01

### 배열에서 자신이 삽입될 위치를 찾는 함수 ###
def findInsertIdx(ary, data):    #ary:배열, data:삽입될 값
    findIdx = -1                 #초깃값은 없는 위치로 지정
    for i in range(0, len(ary)):
        if ary[i] > data:       #배열에서 자신보다 큰 값을 찾으면
            findIdx = i         #그 위치가 삽입될 위치
            break
    if findIdx == -1:            #큰 값을 못 찾음 == 제일 마지막에 위치
        return len(ary)
    else:
        return findIdx

testAry = []
insPos = findInsertIdx(testAry, 55)    #빈 배열에 55를 삽입
print('삽입할 위치 -->', insPos)

testAry = [33, 77, 88]
insPos = findInsertIdx(testAry, 55)     #중간에 55를 삽입
print('삽입할 위치 -->', insPos)         #77을 뒤로 밀고 55가 들어가게 됨


testAry = [33, 55, 77, 88]
insPos = findInsertIdx(testAry, 100)   #자신보다 큰 값이 없을 때 삽입
print('삽입할 위치 -->', insPos)          #4번째에 들어가게 됨

=============실행결과=============
삽입할 위치 --> 0
삽입할 위치 --> 1
삽입할 위치 --> 4

 

 

 

5. 버블정렬01

### 버블 정렬의 구현 ###
def bubbleSort(ary):
    n = len(ary)
    for end in range(n-1, 0, -1):   #end변수 : 각 사이클의 끝 위치 지정
        for cur in range(0, end):    #각 사이클의 맨 앞부터 end-1번까지 반복
            if ary[cur] > ary[cur+1]:  #현재(cur)와 현재 다음(cur+1) 위치 값을 비교  #처음이 더 크면 교환
                ary[cur], ary[cur+1] = ary[cur+1], ary[cur]   #두 값을 교환
    return ary
dataAry = [188, 162, 168, 120, 50, 150, 177, 105]

print('정렬 전 -->', dataAry)
dataAry = bubbleSort(dataAry)
print('정렬 후 -->', dataAry)

=============실행결과=============

정렬 전 --> [188, 162, 168, 120, 50, 150, 177, 105]
정렬 후 --> [50, 105, 120, 150, 162, 168, 177, 188]

 

 

 


6. 버블정렬02

### 개선된 버블 정렬의 구현 ###
def bubbleSort(ary):
    n = len(ary)
    for end in range(n-1, 0, -1):
        # 각 사이클 마다 자리바꿈이 발생되었는지 확인하는 변수 --> changeYN
        # 우선은 자리바꿈이 발생되지 않았다고 가정
        changeYN = False
        print('# 사이클 -->', ary)   #사이클이 몇 번 수행되었는지 체크하려고 배열상태 출력
        for cur in range(0, end):
            if ary[cur] > ary[cur+1]:
                ary[cur], ary[cur+1] = ary[cur+1], ary[cur]
                changeYN = True    #자리바꿈이 발생하면 True로 변경
        if not changeYN:    #changeYN이 False라면 (줄을 똑바로 섰다면) #자리바꿈이 발생되지 않았다면 이미 정렬이 완료된 것이므로
            break   #반복문을 종료
    return ary

dataAry = [50, 105, 120, 188, 150, 162, 168, 177]

print('정렬 전 -->', dataAry)
dataAry = bubbleSort(dataAry)
print('정렬 후 ==>', dataAry)

=============실행결과=============
정렬 전 --> [50, 105, 120, 188, 150, 162, 168, 177]
# 사이클 --> [50, 105, 120, 188, 150, 162, 168, 177]
# 사이클 --> [50, 105, 120, 150, 162, 168, 177, 188]
정렬 후 ==> [50, 105, 120, 150, 162, 168, 177, 188]

 

 

 

 

7. 퀵 정렬 01

### 퀵 정렬의 간단한 구현 ###
def quickSort(ary):
    n = len(ary)
    if n <= 1:        #정렬할 리스트의 개수가 1개 이하라면
        return ary    #이미 정렬된 배열이다.
    pivot = ary[n // 2]   #기준 값을 중간값으로 지정
    # 기준보다 작은 데이터를 저장할 왼쪽 배열,
    # 기준보다 큰 데이터를 저장할 오른쪽 배열을 준비
    leftAry, rightAry = [], []
    for num in ary:
        if num < pivot:     #기준에 따라 왼쪽, 오른쪽 배열에 데이터 저장
            leftAry.append(num)
        elif num > pivot:
            rightAry.append(num)
    #재귀 호출해서 정렬한 후 반환
    return quickSort(leftAry) + [pivot] + quickSort(rightAry)

dataAry = [188, 150, 168, 162, 105, 120, 177, 50]
print('정렬 전 -->', dataAry)
dataAry = quickSort(dataAry)
print('정렬 후 -->', dataAry)

=============실행결과=============
정렬 전 --> [188, 150, 168, 162, 105, 120, 177, 50]
정렬 후 --> [50, 105, 120, 150, 162, 168, 177, 188]

 

 

 

 

8. 퀵 정렬 02

### 퀵 정렬의 간단한 구현 (중복된 값을 고려) ###
def quickSort(ary):
    n = len(ary)
    if n <= 1:
        return ary
    pivot = ary[n // 2]     # 중간값   # 몫
    #기준과 동일한 데이터가 있을 경우에 저장할 midAry를 준비한다.
    #midAry에는 모두 동일한 값이 들어간다.
    leftAry, midAry, rightAry = [], [], []
    for num in ary:
        if num < pivot:
            leftAry.append(num)
        elif num > pivot:
            rightAry.append(num)
        else:
            midAry.append(num)  #기준과 동일한 데이터는 midAry에 저장
    return quickSort(leftAry) + midAry + quickSort(rightAry)

dataAry = [120, 120, 188, 150, 168, 50, 50, 162, 105, 120, 177, 50]

print('정렬 전 -->', dataAry)
dataAry = quickSort(dataAry)
print('정렬 후 -->', dataAry)

=============실행결과=============
정렬 전 --> [120, 120, 188, 150, 168, 50, 50, 162, 105, 120, 177, 50]
정렬 후 --> [50, 50, 50, 105, 120, 120, 120, 150, 162, 168, 177, 188]

 

 

 

 

9. 정렬 - 성능비교 01

### 선택 정렬과 퀵 정렬의 성능 비교하기 ###
import random
import time

## 선택 정렬 ##
def selectionSort(ary):
    n = len(ary)        #배열의 길이
    for i in range(0, n-1):
        minIdx = i
        for k in range(i+1, n):
            if ary[minIdx] > ary[k]:
                minIdx = k
        ary[i], ary[minIdx] = ary[minIdx], ary[i] #0번째 값과 찾은 최솟값을 교환 #맞교환
    return ary



## 퀵 정렬 ##
def quickSort(ary):
    n = len(ary)
    if n <= 1:
        return ary
    pivot = ary[n // 2]     # 중간값   # 몫
    #기준과 동일한 데이터가 있을 경우에 저장할 midAry를 준비한다.
    #midAry에는 모두 동일한 값이 들어간다.
    leftAry, midAry, rightAry = [], [], []
    for num in ary:
        if num < pivot:
            leftAry.append(num)
        elif num > pivot:
            rightAry.append(num)
        else:
            midAry.append(num)  #기준과 동일한 데이터는 midAry에 저장
    return quickSort(leftAry) + midAry + quickSort(rightAry)




## 메인 코드 부분 ##
#임의로 생성할 데이터 개수를 배열에 미리 저장#
countAry = [1000, 10000, 12000, 15000]

for count in countAry:
    tempAry = [random.randint(10000, 99999) for _ in range(count)]
    selectAry = tempAry[:]   #[:]모두 라는 의미   #선택 정렬 배열에 복사
    quickAry = tempAry[:]       #퀵 정렬 배열에 복사

    print(f'## 데이터 수 : {count}개')

    start = time.time()    #선택 정렬 시작 시간 설정
    selectionSort(selectAry)   #선택 정렬 수행
    end = time.time()       #선택 정렬 끝 시간 설정
    print(f'선택 정렬 --> {end-start:8.3f}초')   #걸린 시간을 초 단위로 출력

    start = time.time()   #퀵 정렬 시작 시간 설정
    quickSort(quickAry)    #퀵 정렬 수행
    end = time.time()       #퀵 정렬 끝 시간을 설정
    print(f'퀵 정렬 --> {end-start:10.3f}초')

=============실행결과=============
## 데이터 수 : 1000개
선택 정렬 -->    0.022초
퀵 정렬 -->      0.001초
## 데이터 수 : 10000개
선택 정렬 -->    2.133초
퀵 정렬 -->      0.013초
## 데이터 수 : 12000개
선택 정렬 -->    2.985초
퀵 정렬 -->      0.015초
## 데이터 수 : 15000개
선택 정렬 -->    4.698초
퀵 정렬 -->      0.020초


오늘의 참고 사이트 : 파이썬 튜터 https://pythontutor.com 

 

Python Tutor: Learn Python, JavaScript, C, C++, and Java by visualizing code

Learn Python, JavaScript, C, C++, and Java This coding tutor tool helps you learn Python, JavaScript, C, C++, and Java by visualizing code execution. You can use it to debug your homework assignments and as a supplement to online coding tutorials. Related

pythontutor.com

현재 진행되고 있는 코드에 대한 값과 설명 살펴보기에 유용함


10. 정렬 - 성능비교02

### 이미 정렬된 줄에 끼어들기 : 버블 정렬과 퀵 정렬의 성능 비교 ###
import random
import time

## 퀵 정렬 ##
def quickSort(ary):
    n = len(ary)
    if n <= 1:
        return ary
    pivot = ary[n // 2]     # 중간값   # 몫
    #기준과 동일한 데이터가 있을 경우에 저장할 midAry를 준비한다.
    #midAry에는 모두 동일한 값이 들어간다.
    leftAry, midAry, rightAry = [], [], []
    for num in ary:
        if num < pivot:
            leftAry.append(num)
        elif num > pivot:
            rightAry.append(num)
        else:
            midAry.append(num)  #기준과 동일한 데이터는 midAry에 저장
    return quickSort(leftAry) + midAry + quickSort(rightAry)


## 버블정렬 ##
def bubbleSort(ary):
    n = len(ary)
    for end in range(n-1, 0, -1):
        # 각 사이클 마다 자리바꿈이 발생되었는지 확인하는 변수 --> changeYN
        # 우선은 자리바꿈이 발생되지 않았다고 가정
        changeYN = False
        #print('# 사이클 -->', ary)   #사이클이 몇 번 수행되었는지 체크하려고 배열상태 출력
        for cur in range(0, end):
            if ary[cur] > ary[cur+1]:
                ary[cur], ary[cur+1] = ary[cur+1], ary[cur]
                changeYN = True    #자리바꿈이 발생하면 True로 변경
        if not changeYN:    #changeYN이 False라면 (줄을 똑바로 섰다면) #자리바꿈이 발생되지 않았다면 이미 정렬이 완료된 것이므로
            break   #반복문을 종료
    return ary


## 메인 코드 부분 ##
tempAry = [random.randint(10000, 99999) for _ in range(1000000)] #임의의 데이터 백만개 생성
tempAry.sort()   #파이썬의 정렬 기능을 이용해서 정렬

rndPos = random.randint(0, len(tempAry)-1)   #끼어들 임의의 위치를 선정한다.
print(f'# 데이터 개수 --> {len(tempAry)}')
print(f'# 끼어든 위치 --> {rndPos}')

#이미 정렬된 배열에서 임의의 위치에 배열의 마지막 데이터를 끼워 넣는다.
tempAry.insert(rndPos, tempAry[-1])

bubbleAry = tempAry[:]  #버블 정렬할 배열 복사
quickAry = tempAry[:]    #퀵 정렬할 배열 복사

start = time.time()     #버블 정렬 시작 시간 설정
bubbleSort(bubbleAry)   #버블 정렬 수행
end = time.time()       #버블 정렬 끝 시간 설정
print(f'다시 정렬 시간(버블 정렬) --> {end-start:8.3f}초')

start = time.time()     #퀵 정렬 시작 시간 설정
quickSort(quickAry)     #퀵 정렬 수행
end = time.time()       #퀵 정렬 끝 시간 설정
print(f'다시 정렬 시간(퀵 정렬) --> {end-start:10.3f}초')

=============실행결과=============
# 데이터 개수 --> 1000000
# 끼어든 위치 --> 241139
다시 정렬 시간(버블 정렬) -->    0.271초
다시 정렬 시간(퀵 정렬) -->      1.510초

 

 

 

 

11. openpyxl 예제 05

셀 복사하기 : 여러 셀의 내용을 읽어와 복사해 넣기

## 셀 복사하기 : 여러 셀의 내용을 읽어와 복사해 넣기 ##
from openpyxl import load_workbook

wb = load_workbook(filename='테스트.xlsx')
ws = wb['시트1']       #시트를 선택

src_data = []   #복사할 값을 저장할 리스트
for cell in ws[2]:      #원본이 될 2행에 접근
    src_data.append(cell.value)  #2행의 셀 값들을 리스트에 추가

print(src_data)

for row in ws['A5:C5']:  #A5:C5에 넣겠다
    for cell in row:
        cell.value = src_data[cell.col_idx-1]
wb.save(filename='테스트_셀 복사2.xlsx')

=============실행결과=============
['이순신', '55', '남자']

테스트. xlsx
테스트_셀 복사2..xlsx

 

 

 

셀 병합 및 해제하기

## 셀 병합 및 해제하기 ##
from openpyxl import load_workbook

wb = load_workbook(filename='테스트.xlsx')
ws = wb['시트1']       #시트를 선택

ws.merge_cells('A1:B1') #A1, B1 셀 병합
ws.merge_cells('A2:B2')

ws.unmerge_cells('A2:B2')   #셀 병합 해제

wb.save(filename='테스트_셀 병합.xlsx')

=============실행결과=============

테스트.xlsx
테스트_셀 병합.xlsx

 

 

 

텍스트 형식을 숫자 형식으로 바꾸고 엑셀 함수로 연산하기

## 텍스트 형식을 숫자 형식으로 바꾸고 엑셀 함수로 연산하기 ##
from openpyxl import load_workbook

wb = load_workbook(filename='테스트.xlsx')
ws = wb['시트1']       #시트를 선택

ws['B2'].data_type = 'i'       # [B2] 셀을 정수형으로 변환
ws['B3'].data_type = 'i'        # [B3] 셀을 정수형으로 변환
ws['A4'] = '나이 합계'
ws['B4'] = '=sum(B2:B3)'   #[B4] 셀에 sum 함수 입력

wb.save(filename='테스트_셀 연산.xlsx')

=============실행결과=============

테스트.xlsx
테스트_셀 연산.xlsx

 

 

그 외 교재의 셀 서식들은 혼자 공부 해보기!

 

'Python > 개념정리' 카테고리의 다른 글

python_19일차  (0) 2022.09.02
python_18일차  (0) 2022.09.01
python_17일차  (0) 2022.08.30
python_16일차  (0) 2022.08.27
python_15일차  (1) 2022.08.24
Comments