본문 바로가기

대외활동/ABC 지역주도형 청년 취업역량강화 ESG 지원산업

[220818 ABC 3일차] - PYTHON 기초

반응형

[파이썬(Python)]

1. 파이썬은 1991년 반 로섬이 발표한 프로그래밍 언어이다.

2. 파이썬 이름은 영국의 6인조 코미디 그룹 '몬티 파이썬'에서 가져왔고, 로고는 비단뱀을 모티브로 만들어졌다.

3. 파이썬 문법은 직관적이어서 비전공자도 쉽게 배울 수 있다 라고 말하고 있다.

4. 단점은 다른 프로그래밍 언어보다 느리다. 일반적으로 C언어보다 10~350배 정도 느리다.

5. 단점을 극복하면서까지 이 파이썬이 인기가 있는 이유는

    1) 컴퓨터 성능이 좋으니깐 느린 속도가 단점으로 크게 부각되지 않는 것이다.

    2) 그럼에도 성능이 좋은 프로그램을 쓰고자 한다면 다른 프로그래밍 언어를 학습해야 한다.

    3) 수많은 라이브러리가 공짜(오픈 소스)로 제공된다.

    * 인공지능 툴에 대한 스스로의 개발이 없어도 다른 사람들이 개발한 라이브러리를 내가 활용하는 것이 가능하다.

    4) 다른 프로그래밍 언어와 결합도가 높은 우수한 확장성을 보여주고 있다.

 

[0817 복습!]

# print() 함수와 서식

print("안녕하세요")
print("%d" %100) # %d 는 정수형 십진수(decimal) %x는 16진수 %o는 8진수
print("%x" %100) # 16진수로 표현이 된다는 것!
print("%o" %100) # 8진수로 표현이 된다!

x = "100+100" # 문자열 변수
print(x)
print(type(x))
print("%d" %(100+100)) # 정수형 변수 ==> 100+100의 계산결과를 보여주었으면 좋겠다 라는 것!
print("%d %d" %(100, 200)) # 순서에 맞춰서 변수(입력값과 출력값을)의 갯수를 맞춰주어야 한다.


#이스케이프 문자
print("\n줄바꿈\n연습")
print("\t탭키\t연습")
print("글자가 \"강조\"되는 효과")
print("글자가 \'강조\'되는 효과")
print("\\\\\ 백슬라이스 출력")
print(r"\n \t \" \\를 그대로 출력")

<출력 복습 예제>

# 출력 복습 예제
#0123456789
#123
#  123
#00123
#123.450000
#  123.5
#123.450
#python
#  python

print("0123456789")
print("%d" %(123))
print("%5d" %(123))
print("%05d" %(123.45))
print("%.6f" %(123.45))
print("%7.1f" %(123.5))
print("%7.3f" %(123.45))
print("%s" %("python"))
print("%10s" %("python"))

 

[깊은 복사 vs 얕은 복사]

name1 = ['정우성', '유재석', '호돌이']
name2 = name1

print("name1 = ", name1, ", id(name1) = ", id(name1))
print("name2 = ", name2, ", id(name2) = ", id(name2))

name1[0] = '송지효'

print("name1 = ", name1)
print("name2 = ", name2)

# 출력결과
# name1 =  ['정우성', '유재석', '호돌이'] , id(name1) =  2483669384768
# name2 =  ['정우성', '유재석', '호돌이'] , id(name2) =  2483669384768
# name1 =  ['송지효', '유재석', '호돌이']
# name2 =  ['송지효', '유재석', '호돌이']

- name1 과 name2는 같은 주소값을 가진다는 것을 보여주는 코드이다.

- 우선, 작업자가 name1에 첫번째 값을 정우성에서 송지효로 값이 변경되었다는 것을 확인할 수 있다.

  그런데 실제로 확인해보면 name1 과 name2 변수 모두 정우성 -> 송지효로 값이 변경되었다는 것을 확인할 수 있다.

  즉, 파이썬은 개별 변수의 값을 가지고 행동하는 것이 아니라, 저장되어 있는 변수값의 주소를 저장하고 있는 것이다.

  그래서 name2는 별도의 정우성, 유재석, 호돌이를 name1에서 별도로 받아 따로 저장한 것이 아니라, name1의 주소값을

  받은 것이므로, name1의 값이 변경되면 name2 역시 자동으로 바뀌게 되는 것이다.

- 이 경우의 문제점은 예를 들어 우리가 빅데이터 분석시 철도공사, 타이타닉 등의 원본데이터를 받아서 그대로 분석할 수도 있지만 원본은 보존하고 사본만 사용해야 한다고 해보자. 복사의 특징을 모르면 데이터가 변경될 때마다 자신도 모르게 연결된 여러 데이터가 변경되어 실제 원본이 오염될 수 있다.

 - 깊은 복사를 한번 해보자!

import copy # 외부 라이브러리를 불러오기   copy라는 이름의 라이브러리를 불러오자.
name3 = copy.deepcopy(name1)

#print("name3 = ", name3)

name1[0] = '전소민'
print("name1 = ", name1, ", id(name1) = ", id(name1))
print("name3 = ", name3, ", id(name3) = ", id(name3))  # name1의 값이 변했어도 name3의 값은 변하지 않았다는 것을 알 수 있다!

# 이게 값만 바뀐거! name1과 name3의 주소값은 다르다는 것을 알 수 있다.

print()
print(type(name3))

 [자료형의 종류]

1. int : 정수 자료형으로 양수, 음수의 부호를 가질 수 있다. 기억 장소는 무제한

2. float : 실수 자료형으로 부동 소수점의 수를 갖는다. 크기는 8 byte이다. 3.9x10^324 ~ 1.8x10^308

3. complex : 복소수 자료형으로 실수와 허수로 구성된다. 크기는 16 byte이다.

4. bool : 참과 거짓값 두가지 값을 표현한 자료형이다. (True, Flase)

5. list : 순서를 갖는 형태로 혼합 형태의 자료형을 저장할 수 있다.

6. str : 문자열 자료형으로 크기와 기억 범위는 무제한이고, 큰따옴표나 작은 따옴표로 묶어준다.

print(201, type(201))
print(-201, type(-201))
print(0.5277e-3, type(0.5277e-3))
print(0.5277e-600, type(0.5277e-600))
print(True, type(True))
print('True', type('True'))

long_str='''
내려갈 때 보았네 올라갈 때 보지 못한 그 꽃
정현종의 섬
사람들 사이에 섬이 있다. 그 섬에 가고 싶다.
'''

 - len() 함수 : 문자열이 몇 개의 문자로 이루어져 있는지 확인하는 함수

print(len(long_str))

[연산의 순서]

1순위 : 거듭제곱

2순위 : 곱셈, 나눗셈, 정수 나눗셈, 나머지 나눗셈

3순위 : 덧셈, 뺄셈

* 헷갈리면 괄호를 통해 구분하자.. ex) ((2+3)/5)+(2*3)+5

n = 2
n += 3 ** 6 # 2에다가 3의 6제곱을 곱하자. (3*3*3*3*3*3) + 2 = 731
print(n)

print("2+2-2*2/2*2 = ", 2+2-2*2/2*2)
print("2-2+2/2*2+2 = ", 2-2+2/2*2+2)

- 연산기호 (C언어부터 많이 쓰던 방식)

1. **= : 거듭제곱

2. *= : 곱셈

3. /= : 나눗셈

4. //= : 정수 나눗셈

5. %= : 나머지 나눗셈

6. += : 덧셈

7. -= : 뺄셈

[ bool(불) 관계 연산자 ]

- 관계연산자 (==, >, <, >=, <=, !=), T(True), F(False)로 출력

print(10 == 10) # 10과 10은 동일하다.
print(10 != 100) # 10과 100은 다르다.
print()

print("대전" < "서울")
print("대전" > "서울")
print("가천" < "홍동")
print("가천" > "홍동")
# 가나다 순을 통해 정렬점으로 얘기하는 것 같다!
print()

x = 47
print(10 <= x <= 30)

- 어디에 많이 사용될까?

 : 예를 들어 패스트푸드 구매 횟수에 대한 데이터가 있다고 해보자. 강원도 어린이 한달 평균 햄버거 구매 횟수, 대전 어린이 한달 평균 햄버거 구매 횟수 등을 비교할 수 있다,

   또 예를 들어 보자. 대전역 KTX를 타고 부산을 가고자 하는 사람들 중 9월 한달 예약 취소 비율을 100(T,T,T,T,F,F,F,T,F,F) 의 비율로서 확인할 수 있다.

y = 50
print(50 >= y <= 100)

# 제어문 and, or, not 연산자도 사용한다. ( 그거는 그때가서 배우자 )

[ List (리스트) ]

- 리스트란 여러개의 값을 저장할 수 있는 변수를 말한다.

- 숫자, 문자 123, "123"

- 리스트라는 자료구조는 혼합 형태의 데이터를 저장할 수 있다

- 순서 (index) 를 갖는다.

a_value = [123, "가나다", True, 789]
print(a_value)
print(a_value[2])

- 리스트 자료형은 대괄호를 사용해 만든다. 대괄호 안에는 여러 요소가 올 수 있는데, 요소는 콤마( , )를 사용해서 구분한다.

- 리스트 요소에는 어떤 자료형도 사용할 수 있으며, 모든 요소가 같은 자료형일 필요는 없다.

list_num = [10, 20, 30, 40]
list_str = ["파이썬", "빅데이터", "프로그래밍"]
list_mix1 = [1.5, 47, "모니터", "스마트폰"]

print("list_num = ", list_num)
print(type(list_num))
print("list_str = ", list_str)
print(type(list_str))
print("list_mix1 = ", list_mix1)
print(type(list_mix1))
print()

- 리스트 안에 리스트를 집어넣는 것이 가능하다 => 어떤 자료형도 사용할 수 있다는 것에서 나오는 특징!

list_mix2 = [True, 42.5, "xyz", list_mix1]

print("list_mix2 = ", list_mix2)
print(type(list_mix2))

print()
print("list_mix2 = ", list_mix2[0])
print("list_mix2 = ", list_mix2[1])
print("list_mix2 = ", list_mix2[2])
print("list_mix2 = ", list_mix2[3])

- 위의 코드를 살펴보자, list_mix2의 3번째 요소는 list_mix1그 자체이기 떄문에, list_mix1의 요소 하나하나들이 인덱스를 갖고 있는 것은 아니다. 인덱스 주소는 실제로는 0~3까지의 주소를 갖고 있다. 즉, [1.5, 47, '모니터', '스마트폰']은 list_mix1의 데이터로 mix2에서 볼 때 개별 4개의 값을 가지고 있는 것이 아니라 하나의 값으로 인지해서 저장하고 있다. 그러므로 list_mix2[4]로 하면 47의 값을 가져오는 것이 아니라 오류가 발생한다.

 

< 리스트 자료형의 연산자 ( +, * ) >

- 더하기 연산자는 두 리스트의 요소를 연결해서 새로운 리스트를 만들어준다.

- 곱하기 연산자는 곱한 정수만큼 리스트의 요소를 반복해서 연결한 후 새로운 리스트를 만들어 준다.

list_str1 = ["빅데이터", "프로그래밍"]
list_str2 = ["인공지능", "자동화지능화 기술"]

list_str12 = list_str1 + list_str2

print(list_str12)

list_str11 = list_str1 * 3

print(list_str11)

 

< 리스트 인덱스 >

- 리스트의 각 요소는 각 요소의 위치를 표시하는 인덱스를 이용할 수 있다.

- 인덱스를 이용해서 특정 요소에 접근할 수 있다.

- 리스트의 인덱스는 0부터 시작한다.

- n개의 요소를 갖는 리스트에서 마지막 요소를 가져오려면 [n-1]로 인덱스를 지정한다.

list_value = [1, 2, '빅데이터', '프로그래밍', 4.5, 6, '인공지능', '자동화지능화 기술', 0.007]
print(list_value)

print("list_value[0] = ", list_value[0]) # 첫 번째 값인 1을 출력해준다.
print("list_value[3] = ", list_value[3]) # 세번재 값인 '프로그래밍'을 출력해준다.
print("list_value[-1] = ", list_value[-1]) # 마지막 값인 0.007을 출력해준다.
print("list_value[-3] = ", list_value[-3]) # 마지막에서 세번째인 '인공지능'을 출력해준다.
print()

print("list_value[2][2] = ", list_value[2][2]) 
# 리스트의 인덱스 2의 값인 '빅데이터'에서 위치값이 3번째 값인 '이'만 출력해준다.
# 인덱스를 두번 쓰면 특정한 글자를 가지고 오는 것이 가능하다.
print("list_value[-2][4] = ", list_value[-2][4]) # "자동화기능화 기술"에서 4번째 글자인 '능'의 단어를 가져온다.

 

- 리스트의 요소 중 인덱스로 지정한 요소에 새로운 자료를 입력하여 데이터를 변경할 수 있다.

- 또한, 리스트에서 특정 요소를 제거하려면 del 명령어를 사용한다

#리스트 내의 값을 변경

list_value = [10, 20, 30, "데이터 분석가", 32.57, 47.4712, 50 ,"4차 산업혁명"]

print("list_value = ", list_value)

list_value[3] = "빅데이터 분석가"

print("list_value = ", list_value)
print()

# 리스트 내의 값 삭제
print("list_value = ", list_value)

del list_value[2]
print("list_value = ", list_value)
# 리스트 내 del list_value[2]를 지정하였더니 30의 글자 값이 삭제되었다.

 

< 리스트 슬라이싱 >

- 문법 : 변수명[start:end:step]

- 리스트 데이터에서 슬라이싱 할 시작과 끝 위치를 나타내준다.

- 이때 end의 값의 기준이 슬라이싱 인덱스의 범위에 포함하지 않는다.

- start 가 end 보다 작으면 step 은 양수가 되며 지정범위 (start ~ end-1)내에서 인덱스가 step마큼 증가한 인덱스에 위치한 요소로 리스트를 구성해서 반환한다.

- start가 end보다 크면 step은 음수가 되고, 역순으로 요소를 선택한 리스트를 반환한다.

- step을 생략하면 1로 간주한다. (기본값이 1임)

list_value = [10, 20, 30, "데이터 분석가", 32.57, 47.4712, 50, '4차 산업혁명', 201, 105, 77.123]
print(list_value)
print()

print("list_value[0:4] = ", list_value[0:4])
print("list_value[5:9] = ", list_value[5:9])
print("list_value[:] = ", list_value[:]) # 전체가 출력됨.
print("list_value[:5:2] = ", list_value[:5:2]) # 처음부터 5번째 데이터까지 2 step씩 건너 뛰면서 출력함
print("list_value[:-2:] = ", list_value[:-2:])

예제)

# 리스트 슬라이싱 예제
# 0 10 20 30 40 50 60 70 80 90 100 110 120 130 140 150
# 0 10 20 30 40 50 60 70 80 
# 0 10 20 30 
# 40 50 60 70 80 90 100 110 120 130 140 150
# 0 40 80 120
# 20 60 100 140
# 0 40 80
# 150 140 130 120 110 100 90 80 70 60 50 40 30 20 10 0
# 80 70 60 50 40 30 
# 80 60 40 20 0


list_val = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150]

print(list_val)
print(list_val[0:9])
print(list_val[:4])
print(list_val[4:])
print(list_val[0:13:4])
print(list_val[2:15:4])
print(list_val[:9:4])
print(list_val[::-1])
print(list_val[8:2:-1])
print(list_val[8::-2])

 

-리스트에 특정 데이터 값이 존재하는지 여부 확인 ("찾고자 하는 값" in 리스트명)

list_val = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150]
print(list_val)
print()

del list_val[0:6:2]
print(list_val)
print()

del list_val[0:4]
print(list_val)
print()

# 리스트에 요소가 존재하는지 확인하는거
print("30이 list_val에 포함되어 있습니까? ", 30 in list_val)
print("100이 list_val에 포함되어 있습니까? ", 100 in list_val)

 

(중간 정리)

- 리스트 연산자 : 여러개의 자료형을 구분하지 않고 모두 다 저장해준다. 1차원 배열 리스트를 구성해준다!

- 연산자 기호 + * 를 사용해서 데이터를 붙이고 증가시킬 수 있다.

- 인덱스와 슬라이싱으로 데이터를 탐색할 수 있다.

- in 연산자로 특정 값을 찾을 수 있다.

- del 명령어로 특정 위치값을 찾아서 데이터를 삭제할 수 있다.

[ 리스트 메소드(method) ]

- append, insert, extend, remove, pop, index, count, sort, reverse

1. append() : 리스트의 끝에 데이터를 하나 더 추가해준다

    append => list.append('추가할 데이터')

2. insert() : 원하는 특정한 위치에 데이터를 하나 더 추가해준다.

    insert => list.insert(데이터를 추가할 인덱스의 위치, '추가할 데이터')

3. extend() : 하나의 리스트 안에 새로운 내용을 추가해준다. (한번에 여러개 가능)

    extend => list.extend('추가할 데이터') / list.extend(['여러개의 데이터면', '이렇게 표시한다.'])

4. remove() : 일치하는 값을 삭제해준다.

    remove => list.remove('삭제할 데이터')

5. pop() : 리스트의 맨 마지막 요소를 돌려주고 그 요소는 삭제한다.

    pop => list.pop('찾고자 하는 요소의 인덱스')

6. index() : 찾으려고 하는 데이터의 인덱스 번호(위치)를 알려준다.

    index => list.index('찾으려고 하는 데이터')

7. count() : 찾고자 하는 값의 개수를 알려준다.

    count => list.count()

8. reverse() : 순서를 뒤집는 메소드이다.

    reverse => list.reverse()

list_value = ['유산균', '자연', '바다', '철도']
print(list_value)

list_value.append('마스크')
print(list_value)

#list_value.append('구구단', '비행기') ===> 두개의 변수 추가 불가
#list_value.append(['구구단', '비행기']) ===> 리스트 자체가 하나의 변수로 인식되어서 추가됨.
# ===> append에는 한번에 한개의 값만을 추가할 수 있다.

list_value.insert(2, '드라마')
print(list_value)

list_value.extend(['구구단', '비행기'])
print(list_value)

list_value.remove('바다')
print(list_value)

loc = list_value.index('마스크')
print(loc)

list_value.append('비행기')
print(list_value)
co = list_value.count('비행기')
print(co)

list_value.reverse()
print(list_value)

 [ Tuple(튜플) ]

- list, tuple은 동일한 구조를 가지고 있지만 변경 관점에서 차이를 두고 있다.

- 튜플은 여러 자료를 하나로 묶어서 관리할 수 있다. 여러 자료를 한번에 처리할 때 사용하면 유용하다.

- 튜플은 리스트처럼 여러개의 자료를 하나로 묶어서 처리하는 자료형이다.

- 튜플은 한번 생성하고 나면 변경할 수 없다는 점을 제외하면 리스트와 상당히 유사하다.

- 튜플은 소괄호를 이용하거나 괄호 없이 요소를 입력해서 만든다.

- 튜플도 리스트처럼 연산자, 인덱싱, 슬라이싱 방법을 그대로 사용할 수 있다.

- 하지만 튜플에서는 값을 변경, 추가, 삭제할 수 없다. 즉, append(), insert(), extend(), remove() 등은 사용할 수 없다.

t_num1 = (0,1,2,3,4)
t_num2 = (5,6,7,8,9)

print(t_num1)
print(t_num2)
print()

print(type(t_num1))
print(type(t_num2))
print()

t_num3 = (10,)
t_num4 = "데이터1",

- 위의 코드를 살펴보자. 마지막 단락에서 ,(콤마)가 있고 없고에 따라 자료형이 변한다.

  콤마가 없으면 그냥 일반 문자열로 인식해서 type이 str이 나옴

  콤마가 있으면 연속적인 데이터로 인식하기 때문에 type이 tuple로 나오게 된다.

 

print(t_num3)
print(t_num4)
print()

print(type(t_num3))
print(type(t_num4))
print()

# 인덱스와 슬라이싱이 잘 적용되는 것을 확인할 수 있다.
t_mixed1 = (1,2,'프로그래밍', '파이썬', '기초실력', 3, 4)
print(t_mixed1)
print(t_mixed1[3])
print(t_mixed1[3:5])

- t_mixed1[3] = "예능프로그램" ===> 이렇게 코딩하면 에러뜬다... 튜플은 값을 바꿀 수 없기 때문에 TypeError가 발생한다. 튜플로 되어있으면 특정 데이터 값을 변경하거나 추가하는게 불가능하다.

 

[ set(세트) ]

- 리스트, 튜플, 세트 자료형은 여러 자료를 하나로 묶어서 관리할 수 있다.

- 리스트나 튜플과 유사한 또 다른 자료형으로 set가 있다.

- set도 여러개의 자료를 하나로 묶어서 관리하긴 하지만, 값에 순서가 없고, 같은 값끼리 중복되지 않는 것이 리스트, 튜플과 차이점을 갖는다.

- 리스트 [], 튜플 (), 세트 {}로 구분할 수 있다.

- frozenset(프로즌세트)도 있는데 수정이 아예 불가능한 set(세트)라고 생각하면 쉽다.

list_num1 = ['사과', '배','배','오렌지','감','토마토','토마토']
t_num1 = ('사과', '배','배','오렌지','감','토마토','토마토')

print(type(list_num1))
print(type(t_num1))

set_num = {10,20,30,40,50,30,20}
set_str = {'사과', '배','배','오렌지','감','토마토','토마토'}

- 주의할 점은 set의 변수명을 set로 설정하는 것은 불가능하다는 점이다.

print(type(set_num))
print(type(set_str))
print()

print("list_num1 = ", list_num1)
print("t_num1 = ", t_num1)
print("set_str = ", set_str)
print("set_num = ", set_num)

- 위의 코드 블럭을 살펴보자. 출력 결과 set는 순서도 섞여있고, 중복되는 결과값들은 한번만 출력해주는 것을 볼 수 있다.

  즉, 같은 값끼리 중복되지 않게 저장해주는 특징을 보여준다.

- print("set_str[2] = ", set_str[20]) ==> set는 순서가 없기 때문에 인덱스와 슬라이싱이 불가능하다. 이 경우 TypeError가 발생한다.

- set_str[2] = "감자" ==> 인덱싱이 불가능하기 때문에 TypeError가 발생한다.

 

- 세트는 값을 변경시킬 수 없다. (애초에 인덱싱이 없으니까 불가능)

 

- 세트는 수학적 집합을 사용할 수 있다. 즉, 교집합, 합집합, 차집합을 계산해줄 수 있다.

- 교집합은 & 기호를 이용해서 표현이 가능하다.

- 합집합은 | 기호를 이용해서 표현이 가능하다. 이때, 겹치는 부분은 그냥 한번만 표현해준다.(중복되는 값 없음)

- 차집합은 - 기호를 이용해서 표현이 가능하다.

set_a = {0,1,2,3,4,5}
set_b = {3,4,5,6,7,8}

print()
print("교집합 a와 b : ", set_a&set_b)

print()
print("합집합 a와 b : ", set_a|set_b)

print()
print("차집합 a와 b : ", set_a-set_b)

- 교집합, 합집합, 차집합을 표현할 수 있는 메소드도 존재한다.

- set.intersection() : 교집합

- set.union() : 합집합

- set.difference() : 차집합

# set_a를 중심으로 set_b를 비교했을 때
print()
print(set_a.intersection(set_b)) # 교집합

print(set_a.union(set_b)) # 합집합

print(set_a.difference(set_b)) # 차집합

[ set 메소드(method) ]

- 인덱스, 슬라이스로 값을 변경(추가, 수정, 삭제)는 어렵다

- 별도의 메소드를 이용해서 변경요소를 확인해보자.

- set.add() : 세트 끝에 새로운 값을 추가할 수 있다.

- set.update() : 순서에 맞춰서 저장하지는 않지만, 새로운 값을 추가해준다.

- set.remove() : 특정값을 제거할 수 있다,

- set.insubset() : 부분집합

- set.inuperset() : insubset 과 반대되는 요소인지 확인하는 메소드

- set.indisjoint() : 교집합이 없으면 T, F

set_a = {0,1,2,3,4,5,5,4,3}
print(set_a)
set_a.add(200)

print(set_a)
set_a.update([5,6,7,8])

print(set_a)
set_a.remove(6)

print(set_a)

a = {1,2,3,4,5}
b = {1,2,3}

print(a.issubset(b)) #False
print(b.issubset(a)) #True

print(a.issuperset(b)) #True
print(b.issuperset(a)) #False

print(a.isdisjoint(b)) #False
print(b.isdisjoint(a)) #False

 

- list를 set으로 변환해서 중복값을 삭제하는 것이 가능하다.

a_value = set([1,1,2,2,3,3,4,5])
print(a_value)
print(type(a_value))

 

[ Dictionary(딕셔너리) 자료형]

- 딕셔너리 자료형은 키와 값의 쌍으로 구성된 자료의 묶음이다.

- 리스트나 튜플에서는 요소를 지정하면 요소의 위치에 따라 인덱스가 자동으로 생성된다.

- 원하는 위치의 요소에 접근하려면 반드시 인덱스의 값을 따져봐야 하지만 딕셔너리는 변수 값이 쌍으로 구성되어 있어 인덱스 대신 키를 사용해 값에 접근할 수 있다.

- 딕셔너리는 중괄호를 이용해 만들고, 키와 값이 쌍으로 구성되어 있고, 콜론(:)으로 구분하며, 각 쌍은 콤마(,)로 구분한다.

- 어떠한 종류의 자료형(논리, 문자, 숫자 등)을 사용할 수 있다.

dict_val1 = {1:'복숭아', 2:'배', 3:'사과', 4:'파인애플'}
print(dict_val1)
print(type(dict_val1))
print()

 

- 키 값이 굳이 인덱스 번호가 아니어도 되고, 불(bool) 자료형이어도 되고, 문자열 자료형이어도 된다!

dict_val2 = {1:12345, 5:78912, 7:12398}
dict_val3 = {True: '정답입니다', False:'정답이 아닙니다.'}
dict_val4 = {'ID201':['공유', 17], 'ID202':['서준', 22]}
print(dict_val2)
print(dict_val3)
print(dict_val4)
print()

 

- 여러 자료형을 한번에 저장하는 것도 가능하다

dict_val5 = dict(a=10, b=30.21, c='봄날', d=True, abc=[1,2,3])
print(dict_val5)

 

-딕셔너리는 인덱스 대신에 키로도 접근할 수 있다?

print("dict_val1[1] = ", dict_val1[1]) #[] 안의 숫자가 인덱스가 아니라 키값임,,!
print("dict_val2[5] = ", dict_val2[5])
print("dict_val3[False] = ", dict_val3[False])
print("dict_val4[ID201] = ", dict_val4['ID202'])
print("dict_val5[d] = ", dict_val5['d'])

- 인덱스 같은 느낌이긴 하지만 키를 이용해 데이터에 접근해서 값을 가져온다고 생각하면 된다.

 

- 딕셔너리 키로 값을 변경하고 추가해보자.

dict_user = {'이름' : '박서준', '나이' : 22}
print(dict_user)

# 딕셔너리 자료형의 값을 변경
dict_user['나이'] = 24
dict_user['이름'] = '홍길동'
print(dict_user)

# 딕셔너리 자료형의 값을 추가
dict_user['취미'] = ['게임', '드라이브']
print(dict_user)

#딕셔너리 자료형 삭제(딕셔너리 데이터 해당 키가 있으면 삭제하고 그렇지 않으면 오류를 발생시킨다.)
# del 함수

del dict_user['나이']
print(dict_user)

#del dict_user['직업'] ==> 이렇게 치면 에러뜸. KeyError 가 발생한다.

# in 연산자를 통해 딕셔너리 데이터에 일치하는 키가 있는지 없는지 확인해보자.
dict_user = {'이름' : '박서준', '나이' : 22, '취미' :['게임','드라이브']}
print(dict_user)

print("'취미' in dict_user = ", '취미' in dict_user) 
# 취미라는 키가 존재하므로 True의 값을 반환
print("'직업' in dict_user = ", '직업' in dict_user) 
# 직업이라는 키가 존재하지 않기 때문에 False의 값을 반환한다.

 [ 딕셔너리 메소드 ]

- keys, values, items, update, get, clear

- dict.keys() : 딕셔너리에 생성된 모든 키를 확인하는 메소드

- dict.values() : 딕셔너리에 생성된 모든 값을 확인하는 메소드

- dict.items() : 딕셔너리 키와 값을 쌍으로 모아서 확인시켜주는 메소드

- dict.update('새로운 딕셔너리') : 기존 딕셔너리에 새로운 딕셔너리의 키와 값을 쌍으로 추가해준다.

- dict.get(키값) : 딕셔너리 키에 대응하는 값을 반환하고, 키에 대응하지 않는다면 None을 반환해준다.

- dict.clear() : 딕셔너리의 모든 키와 값을 삭제하고 빈 딕셔너리를 만든다.

dict_num = {0:'공유', 1:'유재석',2:'박서준', 3:'송지효', 4:'전소민', 5:'이광수'}

print(dict_num)
print(type(dict_num))
print()

# dict.keys() = > 디셔너리에 생성된 모든 키를 확인하는 메소드이다.
print("dict_num.keys() = ",dict_num.keys())
# dict.values() => 디셔너리에 생성된 모든 값을 확인하는 메소드
print("dict_num.values() = ",dict_num.values())
# dict.items() => 딕셔너리 키와 값을 쌍으로 모아서 확인시켜주는 메소드
print("dict_num.items() = ",dict_num.items())
print()

dict_num2 = {7:'정준하', 8:'박명수', 9:'정형돈'}

dict_num.update(dict_num2)
print(dict_num)
print()

print(dict_num.get(1))
print(dict_num.get(5))
print(dict_num.get(6))
print()

dict_num.clear()
print(dict_num)

[ 제어문 ]

- 프로그램의 처리 구문은 대체로 위에서 아래로 물 흐르듯 차례대로 실행된다. 경우에 따라 흐름의 방향을 바꾸거나 특정 명령을 반복적으로 수행할 때가 필요하다. 이때 이를 조절해주는 것이 제어문이다.

- 프로그램의 흐름을 지시하는 명령문이나 프로그램에 실행되는 각 구문, 명령어나 함수가 호출되는 순서, 주어진 조건의 결과에 따라 프로그램의 수행 순서를 변경하거나 특정 명령문의 수행 횟수만큼 반복해야 하는 경우가 종종 발생한다. 이런 흐름을 변경하기 위해 사용하는 것이 제어문이다.

 

[ if 문 ]

- 일상생활에서 무수히 많은 선택을 하는 것처럼, 프로그램을 작성할 때 조건에 따라 두 갈래 이상의 흐름을 바꿔야 하는 경우가 종종 발생한다.

- 좀 더 효과적인 프로그램을 작성하기 위해서 조건을 검사하여 동작의 흐름을 바꾸어야 할 때가 있는데 이때 조건 판단 if문을 사용하면 된다.

- 조건을 코딩할 때 if 조건식이나 else 다음에는 항상 콜론(:)을 필수적으로 작성해야 한다.

- 주의할 점은 if문에 속한 모든 수행문의 들여쓰기가 동일해야 한다는 점이다. 한칸이라도 틀리면 오류가 발생한다.

- 들여쓰기 공백 문자의 간격은 정해져 있는 것은 아니다.

- if 조건식 : 

         명령문 1

         명령문 2

no = 12

if no >= 20 :
    print("1등 당첨")
else :
    print("2등 당첨")
print()


num = 1,2,3
if 2 in num:
    print("숫자가 있어요")
else : 
    print("숫자가 없어요")
print()


n_names=['홍길동','이루자','고수영']
if '이루자' in n_names:
    print("내 친구다")
else :
    print("처음 만나서 반가워요.")
print()

 

# 타이타닉 탑승자 중 0~20세 까지만 데이터를 추출하고 싶다.
# 비슷한 예시를 한번 보자
age = 22
if age >=0 and age <=20 :
    print("확인하였습니다.")
    
else :
    print("나이가 많이 있네요.")
print()

- 특정 데이터가 필요할 때 if문을 사용해서 우리가 원하는 데이터만 뽑아내는 것이 가능하다!

 

a_num = 15
b_num = 30

if a_num >= 15 and b_num >= 25 :
    print("숫자 포함")
    print("참값")

if a_num >= 20 :
    pass 
else :
    print("거짓값")

- pass를 작성하면 조건을 만족하더라도 해당 영역에서는 아무것도 수행하지 않는다.

 

[ And 연산자 ]

- and로 연결된 모든 조건이 모두 참이어야 참이 된다.

a = 10
b = 99

if a == 10 and b == 99 : # a 변수값은 10과 같고, b 변수값은 99와 같고 (이 둘을 모두 만족하는지)
    print("a == 10 and b == 99 : 참 True")
else :
    print("a == 10 and b == 99 : 거짓 False")
print()
    
if a == 10 and b != 99 : # a 변수값은 10과 같고 b 변수값은 99가 아닌것 (이 둘을 모두 만족하는지)
    print("a == 10 and b == 99 : 참 True")
else :
    print("a == 10 and b == 99 : 거짓 False")
print()

if a != 10 and b == 99 : # a 변수값은 10가 아니면서 b 변수값은 99인 것 (이 둘을 모두 만족하는지)
    print("a == 10 and b == 99 : 참 True")
else :
    print("a == 10 and b == 99 : 거짓 False")
print()

if a != 10 and b != 99 : # a 변수값은 10가 아니면서 b 변수값은 99가 아닌것 (이 둘을 모두 만족하는지)
    print("a == 10 and b == 99 : 참 True")
else :
    print("a == 10 and b == 99 : 거짓 False")
print()

- 만약에) 대전 공무원이 대전 지역에 사는 취업한 20대 청년들에게 지방정착자금을 제공하고자 한다고 가정해보자

                if 지역 == 대전 and age >= 20 and age <= 29 :

 

[ OR 연산자 ]

- 조건 중 어느 하나라도 만족하면 참이 된다.

a = 10
b = 99

if a == 10 or b == 99 : # a 변수값은 10과 같고, b 변수값은 99와 같고 (둘 중 하나만이라도 만족하는지)
    print("a == 10 or b == 99 : 참 True")
else :
    print("a == 10 or b == 99 : 거짓 False")
print()
    
if a == 10 or b != 99 : # a 변수값은 10과 같고 b 변수값은 99가 아닌것 (둘 중 하나만이라도 만족하는지)
    print("a == 10 or b == 99 : 참 True")
else :
    print("a == 10 or b == 99 : 거짓 False")
print()

if a != 10 or b == 99 : # a 변수값은 10가 아니면서 b 변수값은 99인 것 (둘 중 하나만이라도 만족하는지)
    print("a == 10 or b == 99 : 참 True")
else :
    print("a == 10 or b == 99 : 거짓 False")
print()

if a != 10 or b != 99 : # a 변수값은 10가 아니면서 b 변수값은 99가 아닌것 (둘 중 하나만이라도 만족하는지)
    print("a == 10 or b == 99 : 참 True")
else :
    print("a == 10 or b == 99 : 거짓 False")
print()

- 만약에) 대전시는 대전 또는 충청도 주소지를 가지고 있는 청년들에게 지방정착자금을 제공하고자 한다고 가정해보자

                if 지역 == 대전 or 지역 == 충청남도 or 지역 == 충청북도 :

 

[ NOT 연산자 ]

- 반대로 바꿔준다!

name = "BlockDMask"

if not name == "BlockDMask" :
    print("not name == 'BlockDMask' : True")
else :
    print("not name == 'BlockDMask' : False")
print()

if not name == "blockdmask" :
    print("not name == 'blockdmask' : True")
else :
    print("not name == 'blockdmask' : False")
    
# 출력 결과
# not name == 'BlockDMask' : False
# not name == 'blockdmask' : True

 

[ 다중 if문 ]

- if ~ elif ~ else 문으로 구성된 다중 문의 형식이 있다.

- 만약 조건이 1이 참이면 첫번째 수행문을 실행하고 조건이 거짓이면 다음 조건식을 만나서 참과 거짓을 판단하고 그에 따른 행동을 수행한다.

- if 조건식1 ~ elif 조건식2 ~ elif 조건식3 ~ elif 조건식3 ... ~ elif 조건식n ~ ... ~ else : 수행문

a_value = 89

if a_value >= 90 :
    print("학점은 A")
    
elif a_value >= 80 :
    print("학점은 B")
    
elif a_value >= 70 :
    print("학점은 C")
    
else :
    print("학점은 D")

예제)

#if 문 예제
# score 변수를 만들어서 학점을 직접 입력받고 그에 따라서
# 4.5 이면 신의 경지인
# 4.1 이상이면 완성된 지식인
# 3.5 이상이면 보통 지식인
# 3.0 이상이면 평범한 인재
# 2.0 이상이면 오락문화의 선구자
# 그것도 아니라면 공부에 흥미가 없나요? 라는 문구를 출력

score = float(input("학점은 얼마인가요? : "))

if score == 4.5 :
    print("신의 경지인")
    
elif score > 4.5 :
    print("정확한 학점을 입력하세요")
    
elif score >= 4.1 :
    print("완성된 지식인")
    
elif score >= 3.5 :
    print("보통 지식인")
    
elif score >= 3.0 :
    print("평범한 인재")

elif score >= 2.0 :
    print("오락문화의 선구자")
    
else :
    print("공부에 흥미가 없나요?")

 

[ 중첩 if문 ] 

- 조건을 검사하는 과정이 두번 이상일 때가 많이 있다. 그럴때 사용하는 것이 중첩 if문이 된다.

money = 1000
age = 22

if money >= 500 :
    item = "파인애플"
    
    if age <= 30 :
        msg = "나이가 20대 초반이네요"
    
    else :
        msg = "나이가 20대 후반이네요"
        
else :
    item = "복숭아"
    
    if age <= 30 :
        msg = "나이가 20대 초반이네요"
    
    else :
        msg = "나이가 20대 후반이네요"
        
print(item, ",", msg)

예제 1)

# 대전 A 대학에서 30 이상이고 대학원생이면 기숙사 제공, 그게 아니면 근처 숙박시설 안내 서비스
# 나이가 30 이상이 아니라면, 대학원생이면 근처 숙박시설 안내, 그것도 아니라면 통학권유

age = int(input("age = "))
student = str(input("student = "))

if age >= 30 :
    
    if student == "대학원생" :
        home = "기숙사 제공"
    
    else :
        home = "근처 숙박시설 안내 서비스"
    
else :
    
    if student == "대학원생" :
        home = "근처 숙박시설 안내"
    
    else :
        home = "통학 권유"
        
print(home)

예제 2)

# 90점과 100점 이상이면 A등급, 1등을 출력
# 70점 이상이라면
# 100점 이상으로 입력되었을 떄 잘못 입력하였습니다. 출력
# 80이상이면 2등 
# 70이상이면 3등
# 그것도 아니라면
# 50이상이면 4등 
# 40이상이면 5등 
# 그것도 아니라면
# 등급이 없습니다. 출력

score = int(input("점수를 입력하세요 : "))

if score <= 100 & score >= 90 :
    result = "1등"
    
elif score >= 70: 
    if score > 100 :
        result = "잘못 입력하였습니다."
    
    elif score >= 80 :
        result = "2등"
    
    elif score >= 70 :
        result = "3등"
    
elif score >= 50 :
    if score >= 50 :
        result = "4등"

    elif score >= 40 :
        result = "5등"
        
else : 
    result = "등급이 없습니다."
    
print(result)

- 코드를 간결하게 작성하는게 제일 좋다! (문제없이 작동된다는 원칙하에..)

 

[ 삼항 연산자 ] 

- 참값 if 조건 else 거짓값

- (lambda : '거짓' , lambda : '참')[조건]()

- {True : '참', False : '거짓'}[조건]

- (조건) and '참' or '거짓'

- ((조건) and ['참'] or ['거짓'])[0]

a = 5
res = '참' if a > 3 else '거짓' # if 조건식의 조건이 맞으면 if 앞의 값을 출력한다.
print(res)

# (Lambda : '거짓', Lambda : '참')[조건]()
res = (lambda:'거짓', lambda:'참')[a>3]()
print(res)

#{True : '참', False:'거짓'}[조건]
res = {True:'참', False:'거짓'}[a>3]
print(res)

#(조건) and '참' or'거짓'
res = (a>3) and '참' or '거짓'
print(res)

#((조건) and ['참'] or ['거짓'])[0]
res = ((a>3) and ['참'] or ['거짓'])[0]
print(res)

 

-삼항 연산자

no = 10

if no > 5 :
    re = no*5
else :
    re = no+2

print(re)

re2 = no*5 if no > 5 else no+2
print(re2)

re3 = (lambda:no+2, lambda:no*5)[no>5]()
print(re3)

re4 = {True:no*5, False:no+2}[no>5]
print(re4)

re5 = (no>5) and no*5 or no+2
print(res)

a = 'kbs'
b = 9 if a == 'kbs' else 11
print(b)

예제)

# 정수를 입력받아서 2와 나눗셈을 해서 나머지가 0이면 짝수입니다 출력
# 그렇지 않으면 홀수입니다 출력

num = int(input("정수를 입력하세요 : "))

if num % 2 == 0 :
    print("짝수입니다.")
    
else :
    print("홀수입니다.")
print()

num = int(input("정수를 입력하세요 : "))

re2 = "짝수입니다." if num%2 ==0 else "홀수입니다."
print(re2)
print()

num = int(input("정수를 입력하세요 : "))

re3 = (lambda:"홀수입니다", lambda:"짝수입니다")[num%2 ==0]()
print(re3)
print()

num = int(input("정수를 입력하세요 : "))

re4 = {True:"짝수입니다", False:"홀수입니다"}[num%2==0]
print(re4)
print()

num = int(input("정수를 입력하세요 : "))

re5 = (num%2 ==0) and "짝수입니다" or "홀수입니다."
print(re5)
print()

num = int(input("정수를 입력하세요 : "))

re6 = ((num%2 ==0) and ['짝수입니다.'] or ['홀수입니다.'])[0]
print(re6)
print()

 

[ 반복문 ]

- while, for 문

- 반복문을 사용하는 이유는 코드의 길이를 줄여서 프로그래밍을 더 간결하게 만들기 위해서이다.

- while 문은 블록 내에서 반복 처리할 수행문을 적어두고 주어진 조건이 만족하는 동안 수행문을 반복하는 형태를 갖는다.

- while문은 조건식이 거짓이 되면 반복 처리가 종료된다.

- 만약에 처음부터 조건이 거짓이면 반복할 수행문이 없으므로 반복문 내 명령문을 한번도 실행하지 않게 된다.

- while문은 조건부터 검사하기 때문에 조건식의 변수에 초기값이 반드시 필요하다

- 반복 영역을 벗어나려면 조건이 거짓이면 되니까 반복문 내에 조건이 거짓이 되도록 하는 명령문을 반드시 적어줘야 한다.

- 반복문 벗어나게 안하면 무한루프됨 => 강제종료 해야함(스스로 종료하지 못한다.)

i=5 # 초기값 (초기화한다고 표현)

while i < 10:
    print("안녕하세요")
    i+=1 # i = i+1
    
a = 1
sum_a = 0
# 짝수의 합계만 구하고 싶다.

while a <= 10:
    print(a)
    if a % 2 == 0 :
        sum_a += a # sum_a = sum_a + a
        print("sum_a = ",sum_a)
    a += 1
    
print("최종적으로 sum_a의 값은? : ",sum_a)

 [ 중첩 while문 ]

- 반복문 while 블록 안에 또 다른 while문을 사용할 수 있다. 이를 중첩 while문 이라고 한다.

- 바깥쪽 while 문의 조건이 참이면 안쪽 while문의 조건을 만나게 된다.

- 안쪽 while 문도 참이면 안쪽 while문 반복 블록을 실행한다.

- 안쪽 while문의 조건이 거짓이면 안쪽 반복문을 벗어나고, 다시 바깥쪽 while문의 조건을 검사해서 거짓이면 전체 반복 작업이 마무리된다.

i = 1

while i<=2 :
    j = 1
    
    while j <=3 :
        print("i = " + str(i) + ", j = " + str(j)) 
        # 숫자는 덧셈이 되므로 숫자를 문자로 바꾸어서 덧셈기호를 결합기호로 사용하고자 한다.
        j=j+1
    i += i
    print()

 

color = ['빨강', '녹색', '노랑', '파랑']

a = 0

while a < len(color) :
    print("색상 : ",color[a])
    a += 1
    
print("색상 개수 : ", len(color))
print()

#=======================================================#
while color: # 리스트 변수값을 바로 사용하고 있다.
    print(color.pop())
    
print("색상 개수 : ", len(color))

- 위의 코드를 살펴보자. list.pop() 마지막 값을 제거하는 메소드이다. 즉, while문에서는 color가 빈 list가 될때 까지 실행될거고, while문이 한번씩 돌아갈 때 마다 list값이 마지막 것부터 제거될 것이다.

 

[ 3일차 최종 정리 ]

1. int, float 숫자형 +=   *=   -=   /=   **= 형식으로도 문법을 사용함.

2. str 형태는 문자를 저장하는데 있어서 len(long_a_value) => long_a_value가 가지고 있는 문자의 개수를 확인시켜준다.

3. bool : True, False

4. 관계 연산자 10 == 100, 10 != 100, 10 < 100, if 10 == 100 and 10 <= 100 :

5. list, tuple, set, dictionary는 여러개의 데이터 값을 저장할 수 있다. (1차원 배열을 구성시켜 준다.)

6. list는 + * 연산자를 사용해서 내부의 데이터를 추가할 수 있다. []

7. list 인덱스, 슬라이싱으로 특정 데이터를 선택하고 저장할 수 있다.

8. list 메소드 : append, insert, extend, remove, pop, index, count, reverse, sort(정렬해주는 메소드) 등

9. tuple은 리스트와 동일하고, 인덱스, 슬라이싱을 사용할 수 있다. 하지만 append, insert, extend 등의 메소드는 사용할 수 없다.

10. tuple은 변경이 불가능하다.

11. set는 인덱스, 슬라이싱을 사용할 수 없다. 중복값은 제거된다.

12. set은 update, add, remove 등 메소드를 이용하여 데이터를 변경할 수 있다.

13. 딕셔너리는 {}를 사용하며, 키와 값을 쌍으로 사용한다.

14. 딕셔너리 메소드 : keys, values, items, update, get, clear 등

15. if문으로 조건식을 설정하여 특정 조건에 맞추어 명령문을 수행할 수 있다.

16. while문은 조건식에 맞추어 반복문을 수행해준다.

반응형