1부터 n까지 정수의 합 구하기
print("1부터 n까지 정수의 합을 구합니다.")
n = int(input())
sum = 0
i = 1
while i <=n:
sum += i
i +=1
print(f"1부터 {n}까지의 합은 {sum}입니다.")
while문 반복
어떤 조건이 성립하는 동안 반복해서 처리하는 것을 반복구조라고 하고 일반적으로 루프라고 한다. 이때 while문은 실행하기 전에 반복을 계속할 것인지를 판단하는데 이런 구조를 사전 판단 반복 구조라고 한다.
while 조건식: 명령문
whlie문의 형식으로 조건식의 평가 결과가 참인 동안의 프로그램의 명령문은 반복된다.
이때 while식의 명령문은 루프 본문이라고 부르며 이는 반복의 대상이 된다.
이때 반복을 제어할 때 사용된 i를 카운터용 변수라고 한다.
for문 반복 알아보기
print("1부터 n까지 정수의 합을 구합니다.")
n = int(input())
sum = 0
for i in range(1,n+1):
sum += i
print(f"1부터 {n}까지 정수의 합은 {sum}입니다.")
변수가 하나만 있을 땐 while문보단 for문 사용이 좋다.
수정: for i in range(1이상, n+1미만의 수)이기 때문에 1부터 n+1로 범위를 두고 그 범위를 벗어나지 않을 동안 반복시켜준다.
1+2....+n까지 더해주는 셈
가우스의 덧셈(1부터 n까지 정수의 합을 구하는 공식)
print("1부터 n까지 정수의 합을 구합니다.")
n = int(input())
sum = n *(n+1)//2 #가우스의 덧셈
print(f"1부터 {n}까지 정수의 합은 {sum}입니다.")
range() 함수로 이터러블 객체 생성하기
range() 함수는 이터러블 객체를 생성한다. 이때 이터러블 객체란 무엇일까?
iterable 객체 - 반복 가능한 객체대표적으로 iterable한 타입 - list, dict, set, str, bytes, tuple, range19. for in 반복문, Range, enumerate 에서 iterable한 타입과 iterable한 타입을 확인하는 방법이 있습니다.
출처 : https://wikidocs.net/16068
range(n) | 0이상 n미만의 수를 차례대로 나열하는 수열 |
range(a, b) | a이상 b미만인 수를 차례대로 나열하는 수열 |
range(a, b, step) | a이상 b미만인 수를 step 간격으로 나열하는 수열 |
이터러블 객체는 쉽게 말해서 반복할 수 있는 객체를 말하면 for문과 함께 사용이 가능하다. 이때 이터러블 자료형의 대표는 list(리스트), str(문자열), tuple(튜플)이 있다.
연속하는 정수의 합을 구하기 위해 값 정렬하기
연속하는 정수의 합을 구할 때 시작하는 값이 1이 아닌 정수를 입력받은 경우라면 range()함수에 전달할 시작값과 끝값을 오름차순으로 정렬해야 한다.
print("a부터 b까지의 정수의 합을 구합니다.")
a = int(input())
b = int(input())
if a > b :
a, b = b, a #a가 b보다 크다면 a에 b값을 b엔 a값을 넣어준다.
sum = 0
for i in range(a,b+1):
sum += i
print(f"{a}부터 {b}까지의 정수의 합은 {sum}입니다.")
a와 b를 오름차순으로 정렬한 뒤 다음 해당 범위의 모든 정수를 더하는 프로그램
a, b = b, a #a와 b의 값을 교환(단일 대입문일 때 사용가능)
두 값 교환하기 1
a, b = b, a 단일 대입문의 교환 과정.
- 우변의 b, a에 의해 두 값을 압축한 튜플(b, a)가 생성
- 대입할 때 튜플(b, a)를 다시 풀어 b, a로 만든 다음 각각 a와 b에 대입
반복 과정에서 조건 판단하기 1
print("a부터 b까지의 정수의 합을 구합니다.")
a = int(input("정수 a를 입력하세요."))
b = int(input("정수 b를 입력하세요."))
if a > b :
a, b = b, a #a가 b보다 크다면 a에 b값을 b엔 a값을 넣어준다.
sum = 0
for i in range(a,b+1):
if i < b:
print(f"{i} + ", end = '') #i가 b보다 작은 경우 과정 출력 진행중인 값 뒤엔 +
else:
print(f"{i} = ", end = '') #i가 b보다 커서 결과를 대입하는 경우 최종 값 뒤에 =
sum += i
print(sum)
for문의 반복은 n번, if문 판단은 n번
반복 과정에서 조건 판단하기 1-2
print("a부터 b까지의 정수의 합을 구합니다.")
a = int(input("정수 a를 입력하세요."))
b = int(input("정수 b를 입력하세요."))
if a > b :
a, b = b, a #a가 b보다 크다면 a에 b값을 b엔 a값을 넣어준다.
sum = 0
for i in range(a,b):
print(f"{i} + ", end = '')
sum += i
print(f"{b} = ", end = '')
sum += b
print(sum)
10-1에서 사용한 if문은 추천하지 않는단다.
그 이유는 a가 1이고 b가 10,000일 때 for문에서 10,000번 반복하는 동안 1~9,999번은 i<b가 참이므로 13행이 9,999번 실행되고 마지막 10,000번은 거짓(else문으로 실행)으로 1번만 실행되기 때문에 10-1 코드의 11번째 줄이 저 단 한 번의 실행을 위해서 9,999번 실행되어야 하기 때문에 추천하지 않는다.
이럴 땐 for문 안에 if문을 제외하여 마지막 else문의 줄을 따로 두는 것이 좋다.
두 값 교환하기 2
- a값을 t에 저장한다
- b값을 a에 대입한다
- t에 저장한 처음 a값을 b에 대입한다.
임시용 변수 t를 두어 두 값의 교환도 가능하다.
반복 과정에서 조건 판단하기 2
print("+와 -를 번갈아 출력합니다.")
n = int(input("몇 개를 출력할까요?: "))
for i in range(n):
if i%2 :
print("-", end ='')
else:
print("+",end = '')
print()
for문의 반복은 n번, 나눗셈은 n번 if문 판단은 n번
- i가 홀수면 '-'를 출력합니다.
- i가 짝수면 '+'를 출력합니다.
<이 프로그램의 2가지 문제점>
- for문 반복 시마다 if문 수행한다는 것 즉, 과장해서 n이 50,000번의 수행을 해야 한다면 if문의 수행도 50,000번이 진행된다는 점이다.
- 상황에 따라 유연하게 수정하기 어렵다
print("+와 -를 번갈아 출력합니다.")
n = int(input("몇 개를 출력할까요?: "))
for i in range(n//2):
print("+-", end = '')
if n % 2:
print("+",end ='')
print()
for문의 반복은 n//2번 나눗셈은 2번, if문 판단은 1번
n이 짝수인 경우 출력 | n // 2 번 |
n이 홀수인 경우 출력 | n // 2 번 + n % 2 ("+") |
반복 과정에서 조건 판단하기 3
print("*를 출력합니다.")
n = int(input("몇 개를 출력할까요?: "))
w = int(input("몇 개마다 줄바꿈할까요?: "))
for i in range (n):
print("*", end = '')
if i % w == w - 1: # 0 1 2 3 4 로 인덱스가 구성이 되기 때문
print()
if n % w:
print()
for문의 반복마다 if문을 실행하기 때문에 효율적이지 않다.
print("*를 출력합니다.")
n = int(input("몇 개를 출력할까요?: "))
w = int(input("몇 개마다 줄바꿈할까요?: "))
for _ in range(n//w):
print("*" * w)
rest = n % w
if rest :
print("*" *rest)
for _ in range( ) : (_) 언더바가 중간에 들어가 있는 걸 언더스코어라 부르며 인데스값을 무시한다는 의미로 사용된다.
<설명>
1. *를 n//w번 출력하기
-> 예를 들어 n이 15, w가 5이면 *****를 3번 줄바꿈하여 출력한다. 이때 n이 w의 배수일 때는 모든 출력이 반복문에서 해결이 된다.
2. *를 n % w번 출력 후 줄바꿈하기
-> n에서 w를 나눈 나머지를 rest변수에 저장하고 '*'를 rest개 출력한 뒤 줄바꿈을 한다. 예를 들어 n이 14고 w가 5일 때 rest에는 4가 저장되어 for문 다음에 출력된다. 또한 n이 w의 배수일 때 rest = 0이 되기때문에 어떤 것(=줄바꿈, *)도 출력되지 않는다.
양수만 입력받기
print("1부터 n까지 정수의 합을 구합니다.")
while True:
n = int(input("n의 값을 입력하세요: ")) #입력받는 값이 음수일 때 무한 반복 질문 구문
if n > 0:
break
sum = 0
for i in range(1, n+1):
sum += i
i += 1
print(f"1부터 {n}까지 정수의 합은 {sum}입니다.")
무한 루프와 break문 알아보기
while True:
n = int(input("n의 값을 입력하세요: "))
if n > 0:
break
while문에 True가 사용된 것은 프로그래머가 의도적으로 무한 반복이되도록 만든 것이며 무한루프라고 한다.
여기서 반복문 안의 break 문을 실행하면 반복문이 종료가 되는데 if문을 사용해 탈출하도록 했다.
즉, 양수 입력을 받을 때 까지 무한 반복하도록 구성한 것이다.
이때 파이썬은 사후 판단 반목문(break문 없이도 탈출 가능)을 제공하지 않기 때문에 break 문을 사용해서 양수를 입력받도록 하는 프로그램을 작성하는 것이다. (사후 판단 반복문 = do ~ while 문, repeat ~ until 문등이 있다.)
for문이 종료된 이후 카운터용 변수 i값 살펴보기
while i <= n:
for i in range(시작값, n+1)
while i <= n: 는 while문이 종료될 때 카운터용 변수 i는 n이 아니라 n+1이다.
for i in range(a, b): 는 [a, a+1, a+2, a+3..., b-1]이라는 이터러블 객체를 생성한다. 그리고 이터러블 객체의 값을 하나씩 꺼내 i에 넣어 반복한다. 따라서 for문이 종료될 때 i는 b가 아니라 b-1이다.
직사각형 넓이로 변의 길이 구하기
area = int(input("직사각형의 넓이를 입력하세요.: "))
for i in range(1, area + 1):
if i * i > area: break
if area % i : continue
print(f"{i} x {area//i}")
약수를 나열하는 프로그램으로 실행 결과로 출력된 값들은 모두 입력된 area의 약수이다. for문은 area까지 1씩 증가하며 약수들만 출력시킨다.
i * i가 area를 초과하면 i가 가장 긴 변의 길이가 되기 때문에 예를 들어 입력한 값이 32라고 할 때 i가 6이 되면 6x6으로 36이 되기 때문에 이때 i가 가장 긴 변의 길이가 되기 때문에 프로그램은 종료된다.
continue문은 area가 i로 나누어 떨어지지 않으면 다시 for문의 다음반복으로 진행이 되도록 한다. 예를 들어 32 % 3은 나머지 2가 생기기 때문에 3의 약수가 아니고 따라서 출력할 필요가 없기 때문에 continue문을 사용하여 루프 본문의 나머지 부분을 건너뛰고 다시 조건식으로 돌아가게 합니다.
<while, break, continue 문의 순서도/ for문에서도 break문과 continue문의 동작은 똑같다.>
import random
n = int(input("난수의 개수를 입력하세요.: "))
for _ in range(n):
r = random.randint(10, 99) #10에서 99 사이의 난수 n개 생성
print(r, end =' ')
if r == 13:
print("\n13이 나와 프로그램을 중단합니다.")
break
else:
print(f"\n{n}개의 난수를 생성하여 난수 생성을 종료합니다.")
여기서 주의할 점은 13이 나올 때 else문은 아예 실행이 되지 않는 다는 것이다.
if 조건문에서 랜덤으로 뽑은 난수가 13일 경우 break문에 의해서 바로 프로그램이 종료 된다.
그렇기 때문에 출력을 break문 앞에 둔 것이다.
난수를 생성하는 random.randint( ) 함수 알아보기
random 모듈에 포함된 randint( )함수 random.randint(a, b)는 a이상 b이하인 난수를 생성하여 반환하는 것을 의미한다.
반복문 건너뛰기와 여러 범위 스캔하기
for i in range(1,13):
if i == 8:
continue
print(i, end=" ")
print()
for문이 도는 동안 if 판단문을 그만큼 같이 판단해야 하기 때문에 매우 비효율적이다.
for i in list(range(1,8)) + list(range(9, 13)):
print(i, end=" ")
print()
if문과 continue문이 없이도 빠지는 특정 숫자를 안다면 이렇게 구성할 수 있다.
이때 for문은 생성한 리스트의 원소를 하나씩 꺼내 반복하기 때문에 반복을 위한 연산 비용은 여전히 발생한다.
비교 연산자를 연속으로 사용하는 방법과 드모르간의 법칙
#2자리 양수(10~99)만 입력받기
print('2자리 양수를 입력하세요. ')
while True:
no = int(input('값을 입력하세요.: '))
if no >= 10 and no <= 99:
break
print(f"입력받은 양수는 {no}입니다.")
무한 루프를 빠져가는 조건문을 통해서 2자리 양수만 입력받는 프로그램이다.
비교 연산자를 연속으로 사용한 방법
if 10 <= no <= 99: #no >=10 and no <= 99와 같다.
드모르간의 법칙을 사용한 방법
if not ( no < 10 or no > 99): # no >= 10 and no <= 99와 같다.
- x and y와 not(not x or not y)의 논리값은 같습니다.
- x or y와 not(not x and not y)의 논리값은 같습니다.
드모르간의 법칙은 논리회로 시간에도 잘 등장하는 개념입니다. 그러나 알아도 모르고 몰라도 모르는 개념입니다. 헷갈리거든요.
구조적 프로그래밍이란?
입력과 출력으로 이루어진 구성 요소를 계층으로 배치하여 프로그램을 구성하는 방법을 구조적 프로그래밍(Structured programming)이라고합니다. 구조적 프로그래밍은 순차, 선택, 반복이라는 세 종류의 제어 흐름을 사용합니다. 지금까지 배운 내용은 모두 구조적 프로그래밍의 개념을 바탕으로 합니다.
다중 루프 알아보기
# 구구단 곱셈표 출력하기
print("-" *36)
for i in range(1, 10):
for j in range(1, 10):
print(f"{i * j :3}", end = " ")
print()
print("-" *36)
1 X 1 = 1 이런식의 구구단 출력이 아닌 곱셈 결과만 출력하는 구구단 곱셈표이다.
print(f"{i * j :3}", end = " ")
열 루프에서 i와 j를 3자리로 설정해서 가지런히 반듯하게 출력하기 위해 :3이 사용되었다.
직각 이등변 삼각형으로 출력하기
# 왼쪽 아래가 직각인 이등변 삼각형으로 *출력하기
print("왼쪽 아래가 직각인 이등변 삼각형을 출력합니다.")
n = int(input("길이가 짧은 변의 길이를 입력하세요.: "))
for i in range(n):
for j in range(i+1):
print("*", end = "")
print()
# 오른쪽 아래가 직각인 이등변 삼각형으로 *출력하기
print("왼쪽 아래가 직각인 이등변 삼각형을 출력합니다.")
n = int(input("길이가 짧은 변의 길이를 입력하세요.: "))
for i in range(n): # 0, 1, 2, 3,....n
for _ in range(n - i - 1): # n - i - 1개의 공백 출력
print(" ", end = "")
for _ in range(i+1): # i+1개의 *출력 1개부터 출력시키기 위함
print("*", end ='')
print()
언더스코어를 쓰는 이유는 인덱스 사용이 필요하지 않은 for문이기 때문에 언더스코어를 써서 for문만 사용하기 때문이다.
파이썬의 변수 알아보기
파이썬에서는 데이터, 함수, 클래스, 모듈, 패키지 등을 모두 객체로 취급한다. 객체는 자료형을 가지며 메모리(저장 공간)를 차지한다. 이런 특징 때문에 파이썬의 변수는 값을 갖지 않는다는 특징이 있습니다.
x = 17은 x가 17이라는 값을 갖고 있다고 말할 수 없다. 보통 프로그래밍 언어에서 변수란 값을 저장하는 상자와 같다고 비교하지만 파이썬에서는 이 비유가 맞지 않는다.
- 변수는 객체를 참조하는 객체에 연결된 이름에 불과하다.
- 모든 객체는 메모리를 차지하고, 자료형뿐만 아니라 식별 번호(identity)를 가집니다.
정수 리터럴 17의 식별 번호와 n의 식별번호가 같다. 이는 객체 17을 n으로 참조했다고 생각하면 된다.
# 함수 내부 외부에서 정의한 변수와 객체의 식별 번호를 출력하기
n = 1
def put_id():
x = 1
print(f'id(x) = {id(x)}')
print(f'id(1) = {id(1)}')
print(f'id(n) = {id(n)}')
put_id()
int형 객체에 n(전역 변수) x(지역 변수)가 접근하여 객체 1을 참조했다고 생각하면 된다.
id(1) = 2166158879024
id(n) = 2166158879024
id(x) = 2166158879024
>>>
# 1부터 100까지 반복하여 출력하기
for i in range(1, 101):
print(f"i = {i:3} id(i) = {id(i)}")
i = 1 id(i) = 2198581831984
i = 2 id(i) = 2198581832016
i = 3 id(i) = 2198581832048
i = 4 id(i) = 2198581832080
......
i = 96 id(i) = 2198582023504
i = 97 id(i) = 2198582023536
i = 98 id(i) = 2198582023568
i = 99 id(i) = 2198582023600
i = 100 id(i) = 2198582023632
1~100까지 나열된 이터러블 객체가 생성되고 이 객체에서 i로 식별 번호를 1개씩 꺼내온다. 따라서 i의 값과 식별 번호 둘 다 갱신(즉, i가 1씩 늘어날 때마다 참조하는 곳도 갱신 된다는 뜻이다.)된다는 것을 실행결과에서 알 수 있다.
'자료구조와 알고리즘 > 자료구조와 함께 배우는 알고리즘' 카테고리의 다른 글
Python - 정렬 알고리즘(부제: 정렬 알고리즘의 종류와 사용방법을 알아보자.) (0) | 2021.08.03 |
---|---|
Python - 재귀 알고리즘(부제: 재귀 알고리즘이 무엇인지 알아보고 하노이의 탑을 알아보자) (0) | 2021.07.15 |
Phython - 스택과 큐(부제: 스택과 큐를 알아보며 예외처리가 무엇 인지를 살펴보자!) (0) | 2021.07.05 |
Python - 검색 알고리즘(부제: 검색 알고리즘이 무엇인지 살펴보고, 선형 검색, 이진 검색, 해시법을 알아보자) (0) | 2021.06.26 |
Python - 자료구조와 배열 (0) | 2021.05.31 |