본문 바로가기

1. Python

3/8(수) IT K-DT (5일차) / 9.제어문(반복문)~12.사용자정의함수

 

9. 제어문(반복문)

 

9-1. 반복문

 

9-1-6. zip() 함수

객체가 담고 있는 원소를 엮어서 튜플의 형태로 반환.

(자동으로 튜플의 형태로 반환되는것이 아니라, 코드에 소괄호를 넣어서 반환해주어야 함)
매개변수의 길이가 다를 때는 짧은 매개변수 기준으로 데이터가 엮이고, 나머지는 버려짐.

li1 = [10, 20, 30]
li2 = ['apple', 'banana', 'orange']

for i in range(len(li1)):
  print((li1[i], li2[i]))

 

(10, 'apple')
(20, 'banana')
(30, 'orange')

 

zip() 비교용으로 작성한 코드. len(li1)과 len(li2)가 우연히 일치해서 적용이 가능한 코드로, 

사용하기 좋은 코드는 아님.

위의 코드 대신 사용할 수 있는 코드가 아래의 zip()함수를 이용한 코드.

 

for l1, l2 in zip(li1, li2):
  print((l1, l2))



(10, 'apple')
(20, 'banana')
(30, 'orange')

li1 = [10, 20, 30]
li2 = ['apple', 'banana', 'orange']
for li in zip(li1, li2):
  print(li) # 'li'로 하나로 묶어서 반환할 수도 있음.


(10, 'apple')
(20, 'banana')
(30, 'orange')

for n, A, a in zip('12345', 'ABCDE', 'abcde'):
  print((n, A, a))
  # 문자를 각각 떼어내서 데이터를 만들 수도 있음.


('1', 'A', 'a')
('2', 'B', 'b')
('3', 'C', 'c')
('4', 'D', 'd')
('5', 'E', 'e')

for n, A, a in zip('12345', 'ABCDEF', 'abcde'):
  print((n, A, a))

# 'F'가 있는 중간 데이터는 6개지만, 출력할 때 짧은 매개변수인 5개 기준으로 데이터가 엮이고 
# 나머지 F는 버려짐.

 

('1', 'A', 'a')
('2', 'B', 'b')
('3', 'C', 'c')
('4', 'D', 'd')
('5', 'E', 'e')

 

9-1-7. 리스트(list)와 튜플(tuple)을 for문과 함께 사용하기

 

li1 = ['apple', 'banana', 'orange', 'melon'] # 리스트와 for문을 함께 사용하는 경우
for i in li1:
  print(i, end=' ')


apple banana orange melon 

tu1 = ('apple', 'banana', 'orange', 'melon') # 튜플과 for문을 함께 사용하는 경우
for i in tu1:
  print(i, end=' ')

 

apple banana orange melon 


아래 score 리스트에 저장된 점수가 60점 이상인 학생이 몇 명인지 알아보는 프로그램을 작성해보자.

score = [90, 30, 50, 60, 80, 70, 100, 40, 20, 10]

score = [90, 30, 50, 60, 80, 70, 100, 40, 20, 10] # 이터러블한 객체이다.
count = 0 # count라는 변수를 생성한다.
for i in score:
  if i >= 60:
    count += 1 # i값이 60 이상인 경우 count값이 1씩 증가한다.
print(f'60점 이상인 학생인 수는 {count}명 입니다.')


60점 이상인 학생인 수는 5명 입니다.

 

9-2. 다중 반복문

반복문이 2개 이상 겹쳐져 있는 형태

for i in range(1,4): # 증가값이 생략되어있음. 기본 증가값 1이고 1부터 3까지 출력.
  print(f'😎 i: {i}')
  for j in range(1,4): 
    print(f' 😍 j: {j}') # i가 돌 때마다 j가 매번 도는 결과를 출력


😎 i: 1
 😍 j: 1
 😍 j: 2
 😍 j: 3
😎 i: 2
 😍 j: 1
 😍 j: 2
 😍 j: 3
😎 i: 3
 😍 j: 1
 😍 j: 2
 😍 j: 3

 

 


 '🎃'를 이용하여 아래와 같은 도형을 만들어보자.


'''
🎃 🎃 🎃 🎃 🎃
🎃 🎃 🎃 🎃 🎃
🎃 🎃 🎃 🎃 🎃
🎃 🎃 🎃 🎃 🎃
🎃 🎃 🎃 🎃 🎃
'''

 

for i in range(5): # 시작값 0, 증가값 1이 생략이 되어있음. 0~4까지 5바퀴를 돌릴 예정.
  for j in range(5):
    print('🎃', end=' ')
  print() # 엔터키의 역할로 줄을 나누어 줌
  # i가 세로줄의 수를 담당, j가 가로줄의 수를 담당


🎃 🎃 🎃 🎃 🎃 
🎃 🎃 🎃 🎃 🎃 
🎃 🎃 🎃 🎃 🎃 
🎃 🎃 🎃 🎃 🎃 
🎃 🎃 🎃 🎃 🎃 

 

 

 

'🎃'를 이용하여 아래와 같은 도형을 만들어보자.

🎃 🎃 🎃 🎃 🎃
🎃 🎃 🎃 🎃
🎃 🎃 🎃
🎃 🎃
🎃

 

for i in range(5): 
  for j in range(i, 5): # i값이 0, 1, 2, 3, 4로 차례대로 늘어남.
      print('🎃', end=' ')
  print()

  
🎃 🎃 🎃 🎃 🎃 
🎃 🎃 🎃 🎃 
🎃 🎃 🎃 
🎃 🎃 
🎃 

 

 


'🎃'를 이용하여 아래와 같은 도형을 만들어보자.

🎃
🎃 🎃
🎃 🎃 🎃
🎃 🎃 🎃 🎃
🎃 🎃 🎃 🎃 🎃

for i in range(5): 
  for j in range(i+1): # 종료값이 직전값인 i로 나와야 하므로 i+1을 입력
    print('🎃', end=' ')
  print()



🎃 
🎃 🎃 
🎃 🎃 🎃 
🎃 🎃 🎃 🎃 
🎃 🎃 🎃 🎃 🎃 

 

 


2단부터 9단까지 구구단을 출력하는 프로그램을 작성

 

for i in range(2,10): # '단'을 돌려줄 숫자
  print(f'{i}단')
  for j in range(1,10):
    print(f'{i} * {j} = {i*j}')
  print() # '단'이 넘어갈때마다 줄나눔을 해주는 역할

 

 


2단부터 9단까지 구구단을 출력하는 프로그램을 while문을 이용해서 작성해보자.

 

i = 2
j = 1

while i <= 9 :
  print(f'{i}단')
  while j <= 9 :
    print(f'{i} * {j} = {i*j}')
    j += 1 

  i += 1
  j = 1 

# j가 9까지 돌고 나서, i값이 1 증가할 때, j값을 다시 1로 초기화를 시켜줘야 함. 
# 이 줄이 없으면, 2단만 정상적으로 나오고 3단부터는 출력이 되지 않음.

  print()  # while문은 저절로 초기화가 되지 않기 때문에 직접 초기화를 시켜주어야 함.

 


아래 score 리스트의 요소를 모두 출력하는 프로그램을 작성해보자.

 

score = [[80,90,50],[40,70,30],[90,50,100]]

for i in range(3): # i를 3바퀴를 돌림
  for j in range(3): # j를 3바퀴를 돌림
    print(score[i][j], end=' ')

 

80 90 50 40 70 30 90 50 100 


데이터는 언제든지 바뀔 수 있기 때문에 range(3)과 같이 상수로 고정된 코드는 좋은 코드가 아님. 

   추후에 수정해야 할 가능성이 생김.

 

다른 코드

for i in score:
  for j in i:
    print(j, end=' ')

 

80 90 50 40 70 30 90 50 100 

 

# 위의 코드보다 이 코드를 사용하는 것이 더 편하다.
# end=' '는 세로로 출력이 아니라, 가로로 출력하고 싶을 때 사용

 


9-3. Comprehension

이터러블한 오브젝트를 '생성'하기 위한 방법 중 하나로 파이썬에서 사용할 수 있는 유용한 기능.

 

n = range(0, 10, 1) # 일반적인 이터러블한 객체의 생성.
result = [0 for i in range(n)] 
# 0부터 9까지 1씩 증가되는 10개의 범위를 생성하고, i에 0을 대입하여 리스트를 생성.
print(result) # 이터러블한 객체를 생성.

 

[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

result = [i for i in range(n)]
print(result)


[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
result = [n*n for n in arr]
print(result) # n개의 범위에서 arr의 숫자가 n*n으로 계산이 되어 리스트로 생성이 됨.


[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

 

arr = ['apple', 'banana', 'orange', 'melon'] 
result = [len(string) for string in arr] # 리스트 안의 문자열의 문자 수를 세어서 리스트로 생성이 됨.
print(result)


[5, 6, 6, 5]

result = [n for n in range(10) if n%2==0] # 조건문 if문을 삽입할 수 있음.
print(result)


[0, 2, 4, 6, 8]

 

0부터 100까지의 숫자 중에서 3의 배수이며, 홀수인 숫자만 리스트에 저장하기

 

result = [n for n in range(101) if n%3==0 and n%2==1]
print(result)


[3, 9, 15, 21, 27, 33, 39, 45, 51, 57, 63, 69, 75, 81, 87, 93, 99]

양수는 리스트에 저장하고, 음수는 0으로 변환해서 저장하기

 

arr = [-1, 0 ,-4, 24, 5, -10, 2]
result = [n if n>0 else 0 for n in arr] # n이 있는 앞부분에 조건문 if를 삽입할 수 있음.
print(result)


[0, 0, 0, 24, 5, 0, 2]

arr = []
for i in range(1, 4): # 1 2 3
  for j in range(1, 3): # 1 2
    arr.append(i*j) 
print(arr) # 1*1, 1*2, 2*1, 2*2, 3*1, 3*2로 출력됨


[1, 2, 2, 4, 3, 6]

 

(다른 코드)

 

arr = [i*j for i in range(1,4) for j in range(1,3)]
print(arr)


[1, 2, 2, 4, 3, 6]

result = [[0 for i in range(2)] for j in range(3)] # 이차원 리스트를 생성할 수 있음
print(result) # i는 0이 2개가 있는 리스트, j는 i 리스트 3개를 가진 리스트


[[0, 0], [0, 0], [0, 0]]

 

 

10. 딕셔너리(dictionary)

 

10-1. 딕셔너리(dictionary)

대응관계를 나타내는 자료형으로, key와 value라는 것을 한 쌍으로 갖는 형태.
예를 들어, 사물함의 각각의 key라는 열쇠를 이용해서 저장된 물건인 value를 꺼낼 수 있음.
하나의 딕셔너리의 key는 중복될 수 없지만, value는 중복이 될 수 있음.

 

10-1-1. 딕셔너리 만들기


변수 = {key1:value1, key2:value2 ...}

 

dic1 = {1:'김사과', 2:'반하나', 3:'오렌지', 4:'이메론'} # 하나의 딕셔너리를 생성한다. 중괄호를 사용해서 만든다.
print(dic1)
print(type(dic1)) # 딕셔너리의 타입은 'dict'(딕셔너리)이다.

 

{1: '김사과', 2: '반하나', 3: '오렌지', 4: '이메론'}
<class 'dict'>

 

10-1-2. key를 통해 value를 찾기

 

dic2 = {1:'김사과', 2:'반하나', 3:'오렌지', 4:'이메론'}
print(dic2[1]) # 인덱스와 다르다.
print(dic2[2])
print(dic2[3])
print(dic2[4])


김사과
반하나
오렌지
이메론

 

dic3 = {'no':1, 'userid':'apple', 'name':'김사과', 'hp':'010-1111-1111'} # key값이 문자열인 경우도 가능.
print(dic3['no'])
print(dic3['userid'])


1
apple

 

10-1-3. 데이터의 추가 및 삭제

 

dic4 = {1:'apple'}
dic4[100] = 'orange' # key가 100이고 value가 orange인 값을 추가
print(dic4)


{1: 'apple', 100: 'orange'}

 

del dic4[1] # dic4의 key가 1인 값을 삭제
print(dic4)


{100: 'orange'}

 

10-1-4. 딕셔너리 함수

keys() : key 리스트를 반환

 

dic5 = {'no':1, 'userid':'apple', 'name':'김사과', 'hp':'010-1111-1111'}
print(dic5.keys())


dict_keys(['no', 'userid', 'name', 'hp'])

values() : value 리스트를 반환

 

print(dic5.values())


dict_values([1, 'apple', '김사과', '010-1111-1111'])

items() : key와 value를 한 쌍으로 묶는 튜플을 반환

 

print(dic5.items())


dict_items([('no', 1), ('userid', 'apple'), ('name', '김사과'), ('hp', '010-1111-1111')])

get() : key를 이용해서 value를 반환.

 

print(dic5.get('userid'))
print(dic5.get('age')) 
# 딕셔너리에 해당되는 키가 없다면 value를 반환요청했을 때 None이 출력됨. '가리키는 데이터가 없다'라는 의미.
print(dic5.get('age','나이를 알 수 없음')) # 뒤에 '나이를 알 수 없음'은 None을 대체하여 출력하는 것

 

apple
None
나이를 알 수 없음

in : key가 딕셔너리 안에 있는지 확인할 수 있음. (키워드로, 함수가 아님.)

 

print('name' in dic5) # 실제로 있는 key라면 True가 출력
print('age' in dic5) # 없는 key라면 False가 출력


True
False

 

10-1-5. 반복문을 이용한 딕셔너리 활용

 

dic5 = {'no':1, 'userid':'apple', 'name':'김사과', 'hp':'010-1111-1111'}
for i in dic5:
  print(i, end=' ') # key만 복사하여 가져올 수 있음.


no userid name hp 

for i in dic5.keys():
  print(i, end=' ') # key만 복사하여 가져올 수 있음.


no userid name hp 

for i in dic5.values():
  print(i, end=' ') # value만 복사하여 가져올 수 있음.


1 apple 김사과 010-1111-1111 

for i in dic5:
  print(dic5[i], end=' ') # value만 복사하여 가져올 수 있음. 가장 많이 사용하게 될 방식.

 

1 apple 김사과 010-1111-1111 

 

for i in dic5:
  print(dic5.get(i), end=' ') # value만 복사하여 가져올 수 있음.


1 apple 김사과 010-1111-1111 

각 key를 순회하면서, 각 key에 해당하는 value에 apple이 있는지 확인해보기

 

dic5 = {'no':1, 'userid':'apple', 'name':'김사과', 'hp':'010-1111-1111'}
for i in dic5:
  if dic5[i] == 'apple':
    print('찾았습니다')
  else:
    print('찾지못했음')


찾지못했음
찾았습니다
찾지못했음
찾지못했음

 

11. 세트(set)

 

11-1. 세트(set)

순서가 없어서 어떤 값이 먼저 나올 지 알 수 없고, 중복되는 데이터를 허용하지 않음.
딕셔너리와 비슷하게 중괄호를 사용해서 선언하지만, key는 존재하지 않고 value만 존재하는 자료구조.

 

11-1-1. set 만들기

 

s1 = { }
print(s1)
print(type(s1)) # 처음 빈칸만 있을때는 key, value값 중 무엇이 저장될지를 모르기 때문에 'dict' 타입으로 출력.

{ }
<class 'dict'>

 

s1 = {1, 3, 5, 7}
print(s1)
print(type(s1)) # 중괄호 안에 값이 들어있다면, 'set' 타입으로 출력.


{1, 3, 5, 7}
<class 'set'>

 

 li1 = [1, 3, 5, 7] # 리스트를 세트로 바꿀 수 있음.
 s2 = set(li1)
 print(s2)


{1, 3, 5, 7}

s3 = {1, 3, 5, 7, 9, 1}
print(s3) # 세트 안의 중복되는 '1'이 사라지게 됨. 중복되는 데이터를 허용하지 않기때문.


{1, 3, 5, 7, 9}

li2 = [1, 3, 5, 3, 7, 9, 1]
print(li2) # 리스트는 중복된 값을 허용
s4 = set(li2)
print(s4) # 리스트에서 중복된 데이터가 모두 사라지고 출력. 중복되지 않는 값만 뽑아내고 싶을 때 활용 가능.


[1, 3, 5, 3, 7, 9, 1]
{1, 3, 5, 7, 9}

print(3 in s4) # s4에 3이 있다. True
print(8 in s4) # s4에 8이 들어있다. False
print(8 not in s4) # s4에 8이 들어있지 않다. True


True
False
True

 


11-1-2. set 함수

add() : set에 단일 데이터를 추가

 

s1 = {100, 200}

s1.add(150) # in-place연산에 의해 데이터가 바로 적용이 됨
print(s1)

s1.add(50)
print(s1) # 추가되어 출력된 순서는 불명확함.


{200, 100, 150}
{200, 50, 100, 150}

update() : set에 여러 데이터를 한번에 추가.

 

s2 = {10, 20, 30}
s2.update([40, 50, 60, 20]) # 20은 중복이 되어서 하나만 출력됨.
print(s2)


{40, 10, 50, 20, 60, 30}

remove() : set의 데이터를 제거.

 

s2.remove(50)
print(s2)

s2.remove(70)
print(s2) # 제거할 데이터가 없다면 에러가 발생.


discard() : set의 데이터를 제거.

 

s2 = {10, 20, 30}
s2.discard(50)
print(s2) # 제거할 데이터가 없어도 에러가 발생하지 않고 그냥 넘어가버림.(remove()와의 차이점)


{10, 20, 30}

copy() : set을 복사.

 

s3 = {10, 20, 30}
s4 = s3.copy()
print(s3)
print(s4)
print(id(s3)) # 값은 같지만, id() 함수를 사용했을 때 저장된 메모리주소는 서로 다름.
print(id(s4))


{10, 20, 30}
{10, 20, 30}
140098672137152
140098672137600

id() : 저장된 메모리주소를 10진수로 표현.

li1 = [1, 2, 3, 4]
li2 = li1 # li1의 메모리 주소가 li2로 복사된 상황.
print(id(li1))
print(id(li2)) # 같은 주소를 가리키고 있음.


140098466682432
140098466682432

 

11-1-3. set의 연산자

 

s1 = {10, 20, 30, 40, 50}
s2 = {30, 40, 50, 60, 70}

# 합집합
result = s1 | s2
print(result)

 

{70, 40, 10, 50, 20, 60, 30}

 

result = s1.union(s2) # union()이라는 메서드를 사용할 때.
print(result)


{70, 40, 10, 50, 20, 60, 30}

# 교집합
result = s1 & s2
print(result)

 

{40, 50, 30}

 

result = s1.intersection(s2) # intersection()이라는 메서드를 사용할 때.
print(result)


{40, 50, 30}

# 차집합
result = s1 - s2
print(result)


{10, 20}

 

result = s1.difference(s2) # difference()라는 메서드를 사용할 때.
print(result)


{10, 20}

# 대칭 차집합 (합집합 - 교집합)
result = s1 ^ s2
print(result)


{20, 70, 10, 60}

 

result = s1.symmetric_difference(s2) # symmetric_difference()이라는 메서드를 사용할 때.
print(result)


{20, 70, 10, 60}

 

 

11-2. set와 zip()함수

 

string = 'apple'
li = [1, 2, 3, 4, 5]
tu = ('김사과', '반하나', '오렌지', '이메론', '채애리')

 

print(list(zip(string, li, tu))) # 튜플로 하나씩 데이터를 묶은 것들을 리스트로 묶음

 

 

print(set(zip(string, li, tu))) 
# 튜플로 하나씩 데이터를 묶은 것들을 세트로 묶음. 세트는 항상 불명확한 순서로 출력.

 

 

print(dict(zip(li, tu))) 
# 딕셔너리는 그대로 출력 시 에러가 발생. string을 빼고 출력하면 정상적으로 출력.

 

 

print(dict(zip(string, tu))) 
# key는 중복이 되지 않기 때문에 'p'를 중복하여 key를 가질 수 없음.
# set가 항상 불명확한 순서로 출력되는 이유는 linkedlist에 따라 랜덤의 개념이 아니다.

 

 

12. 사용자 정의 함수

 

12-1. 함수


변수 x, y에 대해 x값이 정해지면 그에 따라 y값을 결정하는 것.(수학적인 의미)
반복적으로 사용되는 가치있는 부분을 묶어서 하나의 집합으로 만듦. (프로그래밍의 의미)
코드를 재활용하기 위한 목적.

 


12-1-1. 이름만 있는 함수 (편의상의 제목)

 


def 함수명():

    함수가 호출되면 실행할 문장
호출 시 : 함수명


 

def func1():
  print('처음으로 만드는 함수')

func1()


처음으로 만드는 함수

for i in range(5):
  func1() # def를 통해 만든 함수도 반복이 가능함.


처음으로 만드는 함수
처음으로 만드는 함수
처음으로 만드는 함수
처음으로 만드는 함수
처음으로 만드는 함수

 

1-2. 매개변수가 있는 함수

 


def 함수명(변수1, 변수2, ...):

    함수가 호출되면 실행할 문장
호출 시 : 함수명(값1, 값2, ...)


 

def func2(num):
  print(f'입력받은 숫자: {num}')
  
func2(10)


입력받은 숫자: 10

def func3(start, end):
  sum = 0
  for i in range(start, end+1):
    sum += i
  print(f'{start}부터 {end}까지의 합: {sum}')
  
func3(1,10)


1부터 10까지의 합: 55