Data_Analysis_Track_33/Python

Python_03(제어문_컴프리헨션)

lsc99 2023. 8. 18. 19:07

알고리즘(Logic)
1. 변수 입력 받기
2. 입력 받은 변수 계산
3. 결과 출력

제어문
기본적으로 프로그램은 순차구조를 가진다.
알고리즘(Logic)의 실행흐름을 다른 순서로 제어하기 위한 구문을 만드는 문법이 제어문이다.
제어문은 조건문과 반복문 두가지 문법이 있다.

조건문 : 프로그램이 명령문들을 실행하는 도중 특정 순서에서 조건에 따라 흐름의 나눠져야 하는 경우 사용한다
파이썬 조건문 : if문 -> 조건이 True일 경우만 특정 구문들을 실행 하는 조건문.
if문 구문 
if 조건:
    명령문1
    명령문2
    ~~~

# 1. 정수를 입력받는다.
num = int(input("정수"))
# 2. 정수가 0이면 "Zero"를 출력한다. (아니면 아무것도 하지 않는다.)
if num == 0:
    print("Zero")
    print("'0'입니다.") # 코드블록 작성시 들여쓰기 (defalut = 4칸)
# 3. "종료"를 출력
print("종료")

num = 10
if not num:   # if문 뒤 조건에는 무조건 bool타입
    print("Zero") # num의 값이 존재하기 때문에 조건 충족 x -> 명령문 실행되지 않음
print("종료")


!코드블록 : 코드블록이란 여러개의 실행명령문들을 묶어놓은 것을 말한다. 
파이썬에서는 코드블록을 작성할 때 들여쓰기를 이용해 묶어준다. 같은 칸만큼 들여쓰기를 한 명령문들이 같은 블록으로 묶인다.  들여쓰기는 관례적으로 공백 4칸(tab)을 사용한다.


조건이 True일 때 실행할 구문과 False일때 실행하는 조건문 (분기가 나뉠때)
if 조건:
    명령문1_1
    명령문2_2
    ~~~
else:   # defalut 처리
    명령문2_1
    명령문2_2
    ~~~

# 1. id를 입력받는다.
id = input("id를 입력하세요:")
# 2-1. 입력받은 id가 5글자 이상이면 "사용할 수 있는 id입니다."를 출력
if len(id) >= 5:
    print("사용할 수 있는 id입니다.")
# 2-2. 5글자 이상이 아니면 "사용할 수 없는 id입니다."를 출력
else:
    print("사용할 수 없는 id입니다.")
# 3. 종료를 출력
print("종료")


조건이 여러개일 때(분기 추가) elif 사용
elif 대신 if를 여러 개 사용하면 독립적으로 모두 실행되기 때문에 조건이 겹치는 등 여러 문제가 발생할 수 있다.
if 조건1:
    명령문1_1
    명령문1_2
    ~~~
elif 조건2:
    명령문2_1
    명령문2_2
    ~~~
elif 조건3:
    명령문3_1
    명령문3_2
    ~~~
else:
    명령문4
if문 작성시 조건은 더 작은 범위의 조건부터 나열해야 한다.

num = int(input("양수입력:"))
if num > 10000: # if문 비교시 더 작은 범위의 수부터 시작해야 한다.
    print("아주 큰 수")
elif num > 1000:
    print("큰 수")
elif num > 100:
    print("보통")
elif num >= 0:
    print("양수")
else:
    print("음수")
print("종료")


반복문 : 특정 구문들을 반복해서 실행할 때 사용한다. 동일한 코드를 여러번 반복하거나 값이 일정하게(규칙적으로) 변하는 코드를 반복할 경우 사용한다.

while문 : 조건이 True인 동안 구문을 반복해서 실행
while 조건:   !조건은 bool 표현식을 기술
    반복할 구문1
    반복할 구문2
    ~~~

l = [1, 2, 3, 4, 5] # 리스트 원소들의 값 + 10 한 것을 출력

cnt = len(l) # 원소의 개수
idx = 0 # index 역할
while idx < cnt:      # idx가 cnt보다 작은 동안 반복실행.
    value = l[idx]    # 원소 한개 조회
    print(value + 10) # 조회한 원소를 처리(+10 값을 출력)
    idx += 1          # 조건을 False로 바꾸는 구문이 없으면 무한반복되기에 index를 증가


for in 문
iterable 객체를 순환조회하는 구문
구문 : 
for value in List:
    print(value)
    ~~~

# l의 원소중 2의 배수(짝수)만 출력
l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
for value in l: # for 변수 in 리스트: -> 변수: 원소를 지정할 변수명
    if value % 2 == 0: # l의 원소중에서 2로 나누었을 때 나머지가 0인 원소들만 추출
        print(value)

while문과 for in 문의 차이점

l = [1, 2, 3, 4] # 리스트 변수 저장

cnt = len(l)
idx = 0
while idx < cnt: # while문
    v = l[idx]
    print(v)
    idx += 1
    
for v in l:
    print(v) # for in 문에서는 while문과 달리 어떤 처리할지만 작성하면 된다. 그래서
    		 # while문보다 간단한 구문으로 만들 수 있다.


continue, break
continue: 현재 반복을 중단하고 다음 반복으로 넘어간다.
break: 모든 반복을 중단한다.

import random 

result = []
# -100 ~ 100까지 양수가 나오면 result 저장, 0이 나오면 종료
while True:
    num = random.randint(-100,100) # -100 ~ 100 사이의 정수중 하나를 무작위로 반환
    if num == 0:
        break # 반복문을 종료
    elif num < 0:
        continue # 다음 반복
    result.append(num)
result
# 종료를 입력하기 전까지 계속 입력
t = input("입력:")
while True:
    print(f">>{t}")
    if t == "종료":
        # 반복을 멈춘다.
        break
    t = input("입력:")


for in 문 연관 내장 함수
range() : 일정한 간격의 연속된 정수를 제공하는 반복가능 객체를 생성(실수 안됨), 구문 : range(시작값, 종료값, 증감치)

시작값부터 종료값-1까지 증감치만큼 증가하는 값을 제공한다.

시작값, 멈춤값, 증감값 모두 정수만 가능하다

시작값과 증감치는 생략 가능하지만 종료값은 생략할 수 없다.
ex) for i in range(1, 10, 2): -> 1, 3, 5, 7, 9 반환
range()를 이용하여 리스트,튜플,셋 생성도 할 수 있다. ex) l = list(range(1, 101)) 튜플,셋의 경우에는 list 자리에 tuple, set

for i in range(5): # 시작값과 증감값 생략, 종료값 : 5
    print(i, end = ", ")
    
l = list(range(1, 100, 5)) # range() 제공값들을 가지는 list 생성
print(l)

range(0, 1.1, 0.1) # 실수는 안됨, 정수만 가능 -> 오류 발생


enumerate() : 현재 몇번째 값을 제공하는지를 나타내는 index와 제공하는 원소를 tuple로 묶어서 반환
구문 : for (index,) i in enumerate(자료구조, start = 1)

start = 시작 index값, 생략시 default값 -> 0

names = ["유재석", "박명수", "홍길동", "정준하"] 
cnt = 0 # cnt와 같은 변수 저장값을 한번에 선언하기 위해 enumerate()를 사용
for name in names:
    print(cnt, name)
    cnt += 1
    
names = ["유재석", "박명수", "홍길동", "정준하"] 
for name in enumerate(names):
    print(name)
    
for index, name in enumerate(names): # tuple 대입
    print(f"{index}. {name}")
    
for index, name in enumerate(names, start = 1): # start = 시작 index값, 생략시 = 0(default)
    print(f"{index}. {name}")


zip() : 여러 개의 lterable 객체를 받아 반복시 같은 index의 값끼리 튜플로 묶어 반환
구문 : for value in zip(리스트1, 리스트2, 리스트3), 

for 리스트1_value, 리스트2_value, 리스트3_value in zip(리스트1, 리스트2, 리스트3)

# 네명의 사람 정보를 이름, 나이, 주소별로 따로 저장. 같은 index의 값이 한사람의 정보.
names = ['유재석', '박명수', '홍길동', '정준하']
ages = [20, 30, 40, 50]
addresses = ["서울", "인천", "서울", "대전"]

# zip으로 묶인 리스트들의 같은 value의 값들을 tuple로 묶어서 반환
for value in zip(names, ages, addresses):
    print(value, value[0], value[1], value[2])
    
for name, age, address in zip(names, ages, addresses): # tuple 대입
    print(f"이름: {name}, 나이 : {age}, 주소 : {address}")
    
for value in enumerate(zip(names, ages, addresses)):
    print(value)

for index, value in enumerate(zip(names, ages, addresses)):
    print(index, value)
    
for index, (name, age, address) in enumerate(zip(names, ages, addresses)):
    print(f"{index} 이름: {name}, 나이 : {age}, 주소 : {address}")


enumerate와 zip 활용 구문 : for (index,) value in enumerate(zip(리스트1, 리스트2, 리스트3)):
zip()이 return해준 값들을 튜플로 묶어서 반환

다음 리스트가 가진 값에 10배의 값을 가지는 값을 (원래값, 10배값) 의 튜플 묶음으로 가지는 리스트를 만드시오 (리스트 컴프리헨션 이용)
# Ex) [(10,100), (30,300), .., (35, 350)]
lst = [10, 30, 70, 5, 5, 120, 700, 1, 35, 35]
lst_compre = [value * 10 for value in lst]
for index, value in enumerate(zip(lst, lst_compre)):
    print(value)


Comprehension : 기존 Iterable의 원소들을 이용해서 새로운 자료구조(List, Dictionary, Set)를 생성하는 구문.
기존 Iterable의 원소들을 처리한 결과나 특정 조건이 True인 값들을 새로운 자료구조에 넣을때 사용.
tuple comprehension은 없다.
list comprehension 구문 : result = [v for v in list], 10배 곱한 값들을 저장하는 경우 -> result = [v * 10 for v in list] 
set comprehension 구문 : result = {v for v in list}, 10배 곱한 값들을 저장하는 경우 -> result = {v * 10 for v in list}
dictionary comprehension 구문 : result = {key : value for index, value in enumerate(l1)}, 

10배 곱한 값들을 저장하는 경우 -> result = {index : value*10 for index, value in enumerate(list)}

l1  = [1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4]
# l1의 원소들에 동일한 처리 (10배)한 결과를 가지는 리스트를 생성
results = [] # 결과를 담을 리스트
for v in l1:
    # print(v * 10)
    results.append(v * 10) # 원소의 10배한 값을 result리스트에 추가
print(results)

# 위와 같은 작업을 리스트 컴프리헨션을 이용 -> for in 처리를 리스트안에 넣어준다.
result2 = [v * 10 for v in l1]
result2

result3 = {v*10 for v in l1} # set comprehension
result3

# l1의 원소 중에서 특정 조건의 값(짝수)만 모아서 새로운 자료구조에 넣기
results4 = []
results_set = set()
for v in l1:
    if v % 2 == 0:
        # print(v)
        results4.append(v) # List에 추가
        results_set.add(v) # set에 추가 -> set은 중복 제거
print(result4)
print(result_set)
   
#  1 ~ 1000 사이의 10의 배수
[v for v in range(1,1001) if v % 10 == 0]


comprehension에 조건식 추가하기 (l1은 미리 저장해둔 리스트이다.)
l1  = [1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4]
2의 배수 구하기 (리스트) -> [value for value in l1 if value % 2 == 0]
2의 배수 구하기 (셋) -> {value for value in l1 if value % 2 == 0}
2의 배수 구하기 (딕셔너리) -> {value : value for value in l1 if value % 2 == 0}
2의 배수 구한 것 인덱스로 순서 나타내는 방법 -> {index : value for index, value in enumerate(l1) if value % 2 == 0}
결과값 : {1: 2, 3: 4, 5: 6, 8: 2, 10: 4} index[1]의 2, index[3]의 4 ..... 으로 나온다.