ASAC-SK플래닛 T아카데미 데이터 엔지니어

25.10.15 5일차 [ 파이썬 기초 개념 강의_(흐름 제어, 조건식, 조건문, 반복문 for)]

Datadesigner 2025. 10. 15. 18:10
  • 10.15 오늘은 제어문에 관한 수업을 진행했다.
    • 제어에 관한 개요와 개념
    • 조건식에 사용되는 연산자
    • if 조건문
    • for 반복문

 

내용 정리

  •  

흐름 제어
  • 제어문 (xx문 -> 해당 라인의 끝을 :으로 표기 ->이하는 코드블럭으로 구성된다는 뜻)
    • 조건문
    • 반복문
  • 코드의 전개 흐름을 컨트롤한다.
    • 일반적인 절차적 흐름은 
      • 1번 라인
      • 2번 라인
      • 3번 라인
    • 흐름 제어를 통해 원하는 목적을 달성하려면
      • 1번 라인
      • 5번 라인 - 점프
      • 6번 라인
      • 5번 라인 - 반복
    • 표현
      • xx문
        • 조건문(if문) , 반복문(for문, while문), 참고(with문, 함수, 클레스,...)
        • 첫 라인의 마지막에 절대 : 을 빼먹지 말것
          • 들여쓰기 -> 코드 블럭을 표현한다
          • 타 언어에선 {} 중괄호로 표현
        • 코드블럭
          • scope(범위, 변수가 작동되는 범위) 가 적용됨-> 지역 변수로 작동
          • 코드블럭 내부에서만 사용 가능함
          • 전역변수 (맨 앞줄에서 정의한 변수) 는 코드 어떤 위치든 접근 가능
조건식

 

  • 특징
    • 조건문, 반복문이 구동되게 하는 기본 전제조건
  • 결론
    • 조건식의 결론은 True(참) 과 False(거짓) 으로 진행된다 -> 불린형
    • False로 인식되는 표현
      • None, 0, 0.0, [], (), {} 
  • 연산자
    • 값 vs 값 비교하는 조건식
A == B | A와 B가 같다.
A != B | A와 B 가 같지 않다.
A > B | A가 B보다 크다. 초과
A < B | A가 B보다 작다. 미만
A >= B | A가 B보다 크거나 같다. 이상
A <= B | A가 B보다 작거나 같다. 이하
not A | 
   - 부정상황을 체킹할 때 사용
ex)  A가 True일때 not A는 False를 출력하게 바꾼다
  • 조건식 vs 조건식
    • 타 언어에서는 쇼트연산자라고 표현함
    • 빠른 처리가 가능하며, 불필요한 연산을 제거함
      • 조건식1 = C1 , 조건식2 = C2
    • C1 or C2
      • C1이 참이면, 그대로 조건 체크 종료
      • C2는 체크할 필요가 없음, 결과에 상관없이 무조건 참
      • C1 이거나 C2
    • C1 and C2
      • C1이 거짓이면 그대로 조건 체크 종료
      • C1이 참이면 C2까지 체크하고 결론 내림
      • C1 이며 C2
    • 기타
      • A is B
      • - A는 B인가?-> 객체 관리하는 내부 id를 비교하는 연산자
      • - 동일 객체인가?
    • a in A
      • - A 안에 멤버로 a가 존재하는가?
값 vs 값
a = 10, b = 11
a == b a != b a < b a > b, a <= b a >= b not a
False True True False True False False
조건식 vs 조건식
a < b or a == b
True -> a가 b보다 작기 때문에 상황 종료

a == b and a < b
False -> a가 b와 같지 않기 때문에 상황 종료

a ==[]
not a
True -> a의 값은 0 = False인데 not 이 붙었으므로 부정해서 True

 

 

조건문

 

  • syntax
    • 컨디션의 개수에 따라 if 문의 구조는 달라진다
      • 컨디션 1개
        • if 조건식:
        •     수행문(statement)
      • 컨디션 2개
        • if 조건식:
        •     수행문(statement)
        • else:
        •     수행문(statement)
      • 컨디션 3개 이상
        • if 조건식:
        •     수행문(statement)
        • elif 조건식:
        •     수행문(statement)
        • else:
        •     수행문(statement)
예제

포스기에 결제금액에 맞는 멘트가 출력되는 시스템을 만들려 한다
조건
- 잔액은 5000원
- 총 결제액이 5000원 초과할 시 'x원이 부족합니다'
- 총 결제액이 5000원 미만일 시 'x원이 남았습니다'
- 총 결제액이 5000원과 일치할 시 '딱 맞게 결제하였습니다'


customer_price = 5000

coffee_price = int(input('금액을 입력해주세요'))
if coffee_price < customer_price:
    print(f'{customer_price - coffee_price}원이 남았습니다')
elif coffee_price > customer_price:
    print(f'{coffee_price - customer_price}원이 부족합니다')
else:
    print('딱 맞게 결제하였습니다.')


1. 변수 설정 -> customer_price = 5000 , coffee_price = int(input('금액을 입력해주세요'))
= 사용자 입력 함수/추후 더 배울 예정
2. 조건문 설정 기본 구성
if 조건식: <- fstring을 이용해서 
    수행문
if 커피값이 결제금액보다 싸면
   잔액을 말해라
elif 커피값이 결제금액보다 비싸면
   모자란 금액을 말해라
else 둘이 같다면
   딱 맞다고 말해라
 

 

 

  • 삼항연산자
    • 공식 지원 x
    • 대체 표현으로 지원
    • 타언어는 지원한다 : ? <- 이게 지원하는거임
  • 적용조건
    • 조건은 2개 (이분법적 상황)
    • 수행문의 결과로 특정 변수에 값이 세팅될 때
  • 이점
    • 표현의 간결함, 한줄로 표현 가능, 직관적 (파이썬 철학에 맞다)
  • 문법
    • 변수 = | 참일때 출력값 | if | 조건식 | else | 거짓일때 출력값 | 순서대로
'구매 가능', '구매 불가능' 두 가지 값을 정리하려 한다.
조건의 결과는 msg변수에 저장

기본 조건문
if customer_price >= coffee_price:
    msg = '구매 가능'
else:
    msg = '구매 불가능'

여기서 삼항연산자로 표현한다면
msg = '구매 가능' if customer_price >= coffee_price else '구매 불가능'
msg <- (print(msg)) 생략표현

 

 

 

반복문

 

  • for문
    • 지정된(정해진 또는 제한된)횟수를 반복 수행
    • for문의 주로 타겟이 되는 자료구조
      • 컬렉션 계열 (리스트, 딕셔너리, 튜플,...)
      • 제너레이터 (range())
    • 문법
      • for 개별 데이터(멤버) in 컬렉션계열 | 제너레이터 :
      •     수행문

기본 리스트 반복문


datas = [1, 2, 3, 4, 5]

for data in datas:
    print( data ) 

1
2
3
4
5

datas = 변수
data = 개별값을 설정해주는 것이다, 변수와 라임을 맞추기 위해서 data로 표현

 

리스트 + 튜플 구조의 데이터에 반복문 처리



datas = [(1,2), (3,4), (5,6)]

다음과 같이 datas의 데이터를 뽑아서 출력하시오
첫번째값 1, 두번째값 2
첫번째값 3, 두번째값 4
첫번째값 5, 두번째값 6

 

for data in datas:
   print(f'첫번째값 {data[0]}, 두번째값 {data[1]}')

파이썬은 간소화 할수 있다면 최대한 간소화 하는것이 좋다.

for data in datas:
   온도, 습도 = data
   print(f'첫번째값 {온도}, 두번째값 {습도}')
- 인덱싱 보기 힘드니 삭제한 것

더 간소화 한다면

for 온도, 습도 in datas:
   print(f'첫번째값 {온도}, 두번째값 {습도}')
- 애초에 온도, 습도에 datas 리스트의 튜플 (1,2), (3,4), (5,6)을 각각 위치에 할당한 것이다.

 

딕셔너리 데이터를 반복문에 처리



subways = {
      'name' : '영등포역'
      'age' : 70
        }
subways
{'name' : '영등포역' , 'age' : 70}

for문을 딕셔너리에 넣으면 키가 출력됨

for subway in subways:
    print(subway)
name
age

여기서 키와 값을 출력하려면

for key in subways:
    print(key, subways[key])
name 영등포역
age 70

- 딕셔너리에 인덱싱 기호는 키에 맞는 값을 출력하는 기호니까!
다른 방식으로 한다면 딕셔너리의 키와 값을 묶어서 반환하는 .items() 함수를 사용하여

for key, value in subways.items():
  print(key, value)
name 영등포역
age 70

 

리스트 + 딕셔너리 형태의 반복문



ktx_stations = [
{   
'name' : '영등포역' ,
      'age' : 70 ,
       'flag' : [1, 2, 3]
},
{   
'name' : '광명역' ,
      'age' : 25 ,
       'flag' : [5, 6, 7]
}
]
ktx_stations 

[{'name': '영등포역', 'age': 70, 'flag': [1, 2, 3]}, {'name': '광명역', 'age': 25, 'flag': [5, 6, 7]}]

이 리스트에서 
영등포역의 년식은 70년
광명역의 년식은 25년
을 출력하려면 어떻게 해야 할까?
for ktx_station in ktx_stations:
  name, age, _ = ktx_station.values()
  print(f'{name}의 년식은 {age}년')

영등포역의 년식은 70년
광명역의 년식은 25년
- 먼저ktx_station은 딕셔너리이다, 여기서 딕셔너리의 값을 반환하는 values()를 사용해서
역, 년식, 리스트를 각각의 
name, age, _ 함수에 대치시켜준다
그 이후 fstring을 사용해서 각자의 위치에 대치시켜주면 된다! _언더스코어 함수는 값을 받은 이후 버려주는 역할을 한다.

 

그렇다면 
영등포역의 년식은 70년, 2
광명역의 년식은 25년, 6
을 반환하려면? 

1. _ 변수의 인덱스[1]을 이용한다
for ktx_station in ktx_stations:
  name, age, _ = ktx_station.values()
  print(f'{name}의 년식은 {age}년, {_[1]}')

2. _ 변수 또한 분해하여 대치시켜준다


for ktx_station in ktx_stations:
  name, age, (_, flag, _) = ktx_station.values()
  print(f'{name}의 년식은 {age}년, {flag}')

딕셔너리에 존재하는 리스트 또한 인덱싱을 사용함과 동시에 한번 더 분해하여 _에 대치시켜 줄 수 있는것이다!
진짜 이거 혼자서는 절대 못풀었다

 

enumerate (통상 딕셔너리) 활용


인덱스를 명시적으로 표현해주는 함수
enumerate() = (인덱스 순서, 키)를 반환함
ktx_station은 영등포역 딕셔너리, 광명역 딕셔너리를 거쳐서 들어갔기 때문에 이제 광명역의 데이터만을 가지고 있다.


for index, key in enumerate(ktx_station):
  print(index, key)

0 name
1 age
2 flag

인덱스와 키, 값도 함께 출력하려면?
items()함수를 사용하여 키와 값을 함께 도출하면 된다

for index, item in enumerate(ktx_station.items()):
  print(index, item)

0 ('name', '광명역')
1 ('age', 25)
2 ('flag', [5, 6, 7])


그런데 키와 값이 튜플로 나와서 보기가 안 좋다. 이러면 한번 더 분해하여 각 값에 대치시켜주며 깔끔하게 정리하면 된다.

for index, (key, value) in enumerate(ktx_station.items()):
  print(index, key, value)

0 name 광명역
1 age 25
2 flag [5, 6, 7]

 

  • range()
    • 특정 범위 내에 수를 생성(공급)하는 함수
    • 제너레이터의 기능을 탑재하고 있음
    • 필요한 때 필요한 만큼 수를 생성-> 메모리를 효율적으로 관리 -> numpy에서 기본적으로 사용
  • 문법
    • range(시작값, 끝값, step) -> 슬라이싱이랑 똑같음

 

for x in range(3):
  print(x)
0
1
2
for x in range (1,3):
  print (x)
1
2
for x in range(1, 12, 2)
1
3
5
7
9
11

 

조건문 + 반복문을 이용하여 짝수만 필터링하기

range(10) 까지의 범위에서 짝수만 출력하여라
단, range(10)은 수정하지 말것

이럴 경우 알고리즘을 생각해본다면

- 먼저 for를 이용하여 출력하는데
- 만약에 홀수이면 출력하지 않는다.
- ~~이면 ~~하거나 하지 않는것은 조건문의 형식이다.

for x in range(10):
  if x % 2 == 0:
    print (x)
0
2
4
6
8

생각보다 간단하게 끝났다.
range(10)의 범위에서 2로 나누었을때 0이 되는 수(짝수)라면 출력하라고 명령한 것이다.

이 때에는 else를 사용하지 않아도 된다. 만약 else일 경우는 출력하지 않기 때문에 아무것도 하지 않는 코드는 필요가 없다.



그리고 아까 비교 연산자인 not을 사용한다면

for x in range(10):
  if not x % 2:
    print(x)

- 이 경우를 설명하자면 1, 3, 5 ,7, 9는 나누었을때 나머지가 1이 나온다. 이는 True 값을 의미하는데 not x을 붙여서 False로 바꾸기 때문에 출력하지 않게 바꾸는 것이다. 이거 진짜 신기했다.
이제 조금 컴퓨터가 어떻게 돌아가는지 알 것 같은 느낌?

 

  • for문 안에 for문이 존재
    • 중첩 반복문
    • 구구단
    • 게임의 타일 세팅
    • 딥러닝CNN(영상 인식에서 많이 사용)에서 필터라 2D이미지를 탐색할 때(특성 추출)

이중 for문으로 구구단 만들기

구구단은 3단~6단으로 설정
3 x 1 = 3
3 x 2 = 6
.
.
.
6 x 9 = 54
등으로 출력한다 생각하면 먼저
변하는 변수를 생각해라
(맨 앞자리) x (가운데 자리) = (곱한 결과)
이 셋을 각각 대치시키면 되는것이다.

for n in range (3, 7): <- 6까지니까 7이다, 맨 앞자리
  for m in range (1,10): <- 1~9니까 10이다, 가운데 자리
    print (f'{n} x {m} = {n * m}') <- fstring 이용하여 값 입력


3 x 1 = 3
3 x 2 = 6
3 x 3 = 9
3 x 4 = 12
3 x 5 = 15
.
.
.
.
6 x 6 = 36
6 x 7 = 42
6 x 8 = 48
6 x 9 = 54



오늘 수업때에 딕셔너리 + 리스트 반복문 파트에서 정말 아무 갈피도 못 잡고 있어서 멘탈이 나갈 뻔했다. 

 

애초에 요구 사항을 듣고 어디서부터 손을 대야 할 지 감도 안잡히는것이다.

 

그리고 강사님이 해설하시며 하나하나 작성해주실때에는 아~ 저렇게 하면 되는구나 쉬운데?

 

막상 내가 다시 해보면 혼돈 파괴 절망

 

알고리즘에 대한 이해가 아직 안되있다.

 

사실 처음 기초평가를 준비할 때에도 암기부분은 모조리 외운다면 됬었지만 제어문과 함수에 관련된 부분은 정말 아무리 작성하고 검토해도

 

도대체 내가 쓴 코드는 왜 안되는거지?

내 머리속에서는 이렇게 하면 될거같은데 왜 하나도 생각이 안 나지?

하며 계속 검토해보면 

왜 여기서는 [ ] 고 이건 ( ) 지?

왜 여기는 . 찍고 여기는 안찍지?

아 또 : 빼먹었네 

진짜 혼자서는 도저히 적응이 안 돼서 힘들었는데 오늘도 약간 그때 어려워했던 때가 기억났다.

 

전공자들, 그리고 실무자들이라면 완전 기본중의 기본일텐데 너무 간단한 것 조차 못하고 있으니 이쪽으로 이해력에 대한 재능이 부족한 것인가에 대한 생각도 하게 되었다.

 

 

 

최근 스케치업 학원에 사정이 있어서 잠깐 다니는 친구가 한 얘기가 생각났다.

 

 

 

" 아니 우리학원에 x,y,z 축도 색깔 다 칠해져있는데 헷갈리면서 진짜 박스 만들고 그룹 짓고 돌리는것도 못하는 사람들도 너무 많더라 왜 이해를 못하지? "

 

 

 

완전 나잖아? 

 

 

처음이고 이 개념이 머리에 들어가 있지 않다면 당연히 헷갈리는게 맞다고 생각한다.

 

학교 다닐 때엔 프로그램 수업은 거의 없고 ( 심지어 학교 다닐 시절엔 스케치업 수업도 없고 3dmax수업만 있었다.)

학생들은 거의 유투브, 블로그랑 친구들, 선배들에게 하나하나 물어보며 직접 부딪히며 프로그램 관련 공부했었다.

 

그럼에도 하나하나 부딪히고 밤새며 직접 도면을 그리고 모델링을 하다보면 어느순간 자연스럽게 그 개념이 머리에서 마치 숨쉬듯 돌아가고 손이 생각보다 더 빠르게 움직이게 된다. 마치 키보드에 타자를 치는 것 처럼 말이다.

 

나는 3학년에서 4학년으로 넘어갈 즈음에 그걸 느꼈던 것 같다.

 

그리고 회사에 다닐때에는 속도가 정말 기하급수적으로 빨라졌다.

 

그렇게 해도 밤 새야 했으니까 ㅋㅋ, 속도랑 기술은 중요하지 않다, 아무리 빨라도 결과물이 별로면 무슨 소용이겠는가.

 

그래서 생각을 하다가 이 코딩에 관련된 기술들과 알고리즘들도 계속 맨 땅에 헤딩하던 그 시절처럼 계속 끊임없이 시도하고 해본다면 어느 순간 자연스레 이해되지 않겠는가 하는 생각이 들었다, 마치 공간에서 내가 느꼈던것처럼.

 

그래서 먼저 이 기술을 공부하고 익히며 체화가 된 사람들이 정말 부러웠다, 하지만 어쩌겠는가 체화는 절대 누가 시켜주지 않는다. 다시금 멘탈을 부여잡고 공부해야지.