학습목표¶

오늘도 화이팅

  1. 변수타입 응용
  2. 열거형
  3. 반복구문, 분기문
  4. 함수

html로 사용가능합니다.
색상적용

In [11]:
url = 'http://www.naver.com'
print('type - ', type(url))

print('주어진 문자열에서 도메인만 추출하고 싶다면? ')
print('com - ', url[-3:])

print()
print('instance method - ', dir(url))
print()
print('find - ', url.find('com'))
print('com - ', url[url.find('com'):])
type -  <class 'str'>
주어진 문자열에서 도메인만 추출하고 싶다면? 
com -  com

instance method -  ['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isascii', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'removeprefix', 'removesuffix', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']

find -  17
com -  com
In [22]:
companyName = '   sk    '
print('type - ', type(companyName) , 'len - ', len(companyName))
print('strip - ', companyName.strip() , 'len - ', len(companyName.strip()))
type -  <class 'str'> len -  9
strip -  sk len -  2
In [29]:
companyName = 'samsung'
print('첫번째 문자를 대문자로 변경해서 출력 - ', companyName.capitalize())
첫번째 문자를 대문자로 변경해서 출력 -  Samsung
In [45]:
# Quiz
# 제공되는 문자열에서 파일의 확장자가 .xls 파일인지를 확인하고 싶다면?
fileName = 'report.xls'
print('flag - ', fileName.endswith(".xls"))
print('flag - ', fileName.rsplit('.', 1)[-1] == "xls")
flag -  True
flag -  True
  • 함수
In [48]:
# worker function
def printCoin():
    print('코인')
In [49]:
# caller
printCoin()
코인
In [56]:
def greet(name):
    return f"Hello~ , {name}"
In [57]:
result = greet('jslim')
print(result, type(result))
Hello~ , jslim <class 'str'>
In [67]:
lst = [1,2,3,4,5,6,7]
print('type - ', type(lst), bool(lst))
print()
print('max - ', max(lst))
print('min - ', min(lst))
print('sum - ', sum(lst))
print('mean - ', sum(lst) / len(lst) , type(sum(lst) / len(lst)))
print('mean - ', int(sum(lst) / len(lst)) , type(int(sum(lst) / len(lst)))) # 캐스팅 int를 지정
type -  <class 'list'> True

max -  7
min -  1
sum -  28
mean -  4.0 <class 'float'>
mean -  4 <class 'int'>
  • 파이썬에서 사용하는 모든 데이터타입은 참조타입으로 변수에 값이 아닌 주소값을 담는다.
In [75]:
lstTmp01 = [1,2,3]
lstTmp02 = [1,2,3]

print('instance address - id() ', id(lstTmp01), id(lstTmp02))
print('is - 주소번지를 비교하는 연산자 ', lstTmp01 is lstTmp02)

lstTmp03 = lstTmp01
print('is - 주소번지를 비교하는 연산자 ', lstTmp01 is lstTmp03)
instance address - id()  2835138787328 2835153284480
is - 주소번지를 비교하는 연산자  False
is - 주소번지를 비교하는 연산자  True
  • 얕은 복사 vs 깊은 복사
  • 기본모듈이 아닌것들은 반드시 import , from ~ import 구문을 활용해서 사용 승인을 얻어야 함.
  • immutable : 불변(Numeric, text, tuple, bool, str) : 값 변경시 새로운 객체가 생성
  • Mutable : 가변(list, dict, set) : 값 자체를 변경할 수 있는 타입
In [106]:
from copy import copy, deepcopy

original = [[1,2],[3,4]]

shallowCopy = copy(original) # 얕은 복사
print('instance address - id() ', id(original[0]), id(shallowCopy[0]))
deepCopy = deepcopy(original) # 깊은 복사
print('instance address - id() ', id(original), id(deepCopy))

original[0][0] = 2
print('shallowCopy - ', shallowCopy) # 얕은 복사는 원본의 영향을 받는다
print('deepCopy    - ', deepCopy) # 깊은 복사는 원본의 영향을 받지 않는다
instance address - id()  2835158214592 2835158214592
instance address - id()  2835158209216 2835158135168
shallowCopy -  [[2, 2], [3, 4]]
deepCopy    -  [[1, 2], [3, 4]]
In [105]:
# 복사에 취약점
import copy
userData = {'id' : 1, 'token' : 'secret1234'}
cache = copy.copy(userData) # str 불변이라서 새로운 객체가 만들어짐

userData['token'] = 'secret4321'
print(userData['token'])
print(cache['token'])
secret4321
secret1234
In [111]:
import copy
userData = {'id' : 1, 'roles' : ['admin', 'user']}
cache = copy.copy(userData)

userData['roles'].append('guest') # list는 가변이기 때문에 객체를 그대로 사용 -> 원본의 변화에 영향을 받음
print(userData)
print(cache)
{'id': 1, 'roles': ['admin', 'user', 'guest']}
{'id': 1, 'roles': ['admin', 'user', 'guest']}

열거형 : 숫자형 값을 생성하는 객체타입¶

  • range(start, end-1, step)

  • range(end-1)

  • range(start, end-1)

  • 가변인자함수

In [127]:
#rangeTmp = range(1, 11, 2)
#rangeTmp = range(11)
rangeTmp = range(1, 11)

print('data - ', rangeTmp, type(rangeTmp))
print('dir - ', dir(rangeTmp))

# for 변수 in 열거형 : (반복문)
for data in rangeTmp:
    print(data, end='\t')
data -  range(1, 11) <class 'range'>
dir -  ['__bool__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'count', 'index', 'start', 'step', 'stop']
1	2	3	4	5	6	7	8	9	10	
In [123]:
lst = [10, 20, 30]

for data in lst:
    print(data)

print()
for idx in range(len(lst)):
    print('idx - ', idx, 'data - ', lst[idx])
10
20
30

idx -  0 data -  10
idx -  1 data -  20
idx -  2 data -  30
In [301]:
#import random
from random import randint

# append() : 데이터를 0부터 추가
lst = []

for idx in range(10):
    lst.append(randint(1,5))
    
print('data - ', lst)
print()

# print('dir - ', dir(lst))
lst.sort()
print('sort - ', lst)
lst.sort(reverse = True)
print('sort - ', lst)
data -  [5, 5, 5, 4, 2, 1, 4, 4, 2, 4]

sort -  [1, 2, 2, 4, 4, 4, 4, 5, 5, 5]
sort -  [5, 5, 5, 4, 4, 4, 4, 2, 2, 1]
  • 프로그램의 흐름을 제어하는 구문 (if ~ in)
  • True, False 조건처리
In [169]:
if 6 in lst:
    print('find - ')
else :
    print('not found')
not found

list comprehension¶

  • [실행문 for 변수 in 열거형객체]
  • [실행문 for 변수 in 열거형객체 if 조건식]
In [178]:
lst = [2,4,1,5,8,4]

for data in lst:
    print(data, end='\t')

print()
for idx in range(len(lst)):
    print(lst[idx], end='\t')
2	4	1	5	8	4	
2	4	1	5	8	4	
In [203]:
# Quiz : 리스트에 있는 각각의 값을 제곱한 결과를 확인하고 싶다면?
# 연산자 : % (나머지)
for data in lst:
    print(data*data, end='\t')
print()
for idx in range(len(lst)):
    print(lst[idx]*lst[idx], end='\t')
print()

result = []
for idx in range(len(lst)):
    result.append(lst[idx]**2)
print(result)
print()

result = [lst[idx]**2 for idx in range(len(lst))]
print(result)
print()

# Quiz : 제곱한 결과에서 2의 배수인 값들만 추출하고 싶다면?
result = []
for idx in range(len(lst)):
    if (lst[idx]**2 % 2) == 0:
        result.append(lst[idx]**2)
print(result)
print()

result = [lst[idx]**2 for idx in range(len(lst)) if (lst[idx] % 2) == 0 ]
print(result)
4	16	1	25	64	16	
4	16	1	25	64	16	
[4, 16, 1, 25, 64, 16]

[4, 16, 1, 25, 64, 16]

[4, 16, 64, 16]

[4, 16, 64, 16]
In [215]:
# Quiz
# range() 객체를 이용해서 1 ~ 100 사이의 3의 배수만 List 에 담아서 출력한다면?

result = []
for idx in range(1,101):
    if (idx % 3) == 0:
        result.append(idx)
print('case01 - ', result)

print()

result = []
result = [ data for data in range(1,101) if (data % 3) == 0 ]
print('case02 - ', result)
case01 -  [3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57, 60, 63, 66, 69, 72, 75, 78, 81, 84, 87, 90, 93, 96, 99]

case02 -  [3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57, 60, 63, 66, 69, 72, 75, 78, 81, 84, 87, 90, 93, 96, 99]

dict¶

  • 키 중복은 허용하지 않는다.
  • 가변
  • 열거형이 아니므로 순서가 존재하지 않는다.
  • 주의사항) 키값으로 불변(immutable)이 아닌 타입은 정의할 수 없다(list X)
In [233]:
# 사용자 정보를 저장

user = {
    "id" : 100,
    "name" : "admin",
    "role" : "superuser"
}
print(user)

# 권한 변경 함수
def updateRole(data , newRole):
    data["role"] = newRole
    
#caller
updateRole(user, "guest")
print(user)
{'id': 100, 'name': 'admin', 'role': 'superuser'}
{'id': 100, 'name': 'admin', 'role': 'guest'}
In [222]:
# 키 유무를 판단하고 싶다면?
# in : 조건에 맞는 논리값 반환
print("key 유무 판단 - ","id" in user)
print("key 유무 판단 - ","birth" in user)

print("key 통한 데이터 접근 - ", user["id"])
print("key 통한 데이터 접근 - ", user.get("id"))
user["address"] = "seoul"
print('data - ', user)
key 유무 판단 -  True
key 유무 판단 -  False
key 통한 데이터 접근 -  100
key 통한 데이터 접근 -  100
data -  {'id': 100, 'name': 'admin', 'role': 'superuser', 'address': 'seoul'}
In [254]:
# 사용자 정보를 저장
# 보안 관점에서 코드 개선 (불변 데이터 사용, 입력값 검증)

from copy import deepcopy

user = {
    "id" : 100,
    "name" : "admin",
    "role" : "superuser"
}
print(user)

# white list
allowedRoles = {"user", "guest", "manager"}

# 권한 변경 함수
def updateRole(data , newRole):
    copyUser = deepcopy(data)

    # 입력값 검증을 위한 조건 처리 (if ~ in)
    # if newRole in allowedRoles:
    #     data["role"] = newRole
        
    if newRole not in allowedRoles:
        print(f"허용되지 않는 변경 : {newRole}")
    else :
        copyUser["role"] = newRole
    
    return copyUser
    
#caller
changeUser = updateRole(user, "guest")
print('original - ' , user)
print('copy - ' , changeUser)
{'id': 100, 'name': 'admin', 'role': 'superuser'}
original -  {'id': 100, 'name': 'admin', 'role': 'superuser'}
copy -  {'id': 100, 'name': 'admin', 'role': 'guest'}
  • dict를 만드는 다양한 방식
In [255]:
prodJson = {
    'melon' : {'price' : 100, 'qty' : 10},
    'bravo' : [200, 50], 
    'bibigo': [('price', 100),('qty' , 100)]
}
print(prodJson)
{'melon': {'price': 100, 'qty': 10}, 'bravo': [200, 50], 'bibigo': [('price', 100), ('qty', 100)]}
In [256]:
dictTmp = dict(city = 'busan', expo = 2030)
print(dictTmp)
{'city': 'busan', 'expo': 2030}
In [258]:
dictTmp = dict([
    ('city', 'busan'),
    ('expo', 2030)
])
print(dictTmp)
{'city': 'busan', 'expo': 2030}
  • zip()
In [278]:
keys = ('key01', 'key02', 'key03', 'key04')
datas = ('sk', 'samsung', 'lg', 'lgcns')

dictZip = dict(zip(keys, datas))
print(dictZip)
print()
#print(dir(dictZip))

for key in dictZip :
    print(key, dictZip[key])
    
print()
for data in dictZip.keys() :
    print(data)   

print()
for data in dictZip.values() :
    print(data)    

print()
for key, data in dictZip.items() :
    print(key, ' - ' ,data)       
{'key01': 'sk', 'key02': 'samsung', 'key03': 'lg', 'key04': 'lgcns'}

key01 sk
key02 samsung
key03 lg
key04 lgcns

key01
key02
key03
key04

sk
samsung
lg
lgcns

key01  -  sk
key02  -  samsung
key03  -  lg
key04  -  lgcns
In [299]:
# Quiz
# 단어의 빈도수를 구한다면?
# 출력예시 { dog : 3 , cat : 4 , word : 1 , cs : 2 , sk : 2 }
# list 가지고 있는 매서드 : count
# dict 키의 중복을 허용하지 않는다는 점을 확인 : for ~ in(if)
wordLst = ['dog', 'dog', 'cat', 'cat', 'word', 'dog', 'cat', 'cs', 'cat', 'cs', 'sk', 'sk']

wordCount = {}

for w in wordLst:
    if w in wordCount:          
        wordCount[w] += 1       
    else:
        wordCount[w] = 1        

print(wordCount)

#print(dir(wordLst))
#print(wordLst.count('dog'))

#set(wordLst)
#[wordLst.count(data) for data in set(wordLst)]
result = dict(zip(set(wordLst),[wordLst.count(data) for data in set(wordLst)]))
print(result)
{'dog': 3, 'cat': 4, 'word': 1, 'cs': 2, 'sk': 2}
{'dog': 3, 'cs': 2, 'cat': 4, 'sk': 2, 'word': 1}
In [300]:
# Quiz
# 중복을 제거하고 유니크한 값을 출력하라

gender = ['남', '여', '여', '남', '남', '남', '여', '여']

setGender = set(gender)
print(setGender)
{'여', '남'}
In [1]:
# 개선된 코드 
print('case01 - ')
wordLst = ['dog', 'dog', 'cat', 'cat', 'word', 'dog', 'cat', 'cs', 'cat', 'cs', 'sk', 'sk'] 
unique  = sorted(set(wordLst))
freq    = [wordLst.count(word) for word in unique]
result  = dict(zip(unique, freq))

print(result)

print('case02 - ')
from collections import Counter
result = dict(Counter(wordLst))
print(result)

print('case03 - ')
result = {key: wordLst.count(key) for key in dict.fromkeys(wordLst)}
print(result)
case01 - 
{'cat': 4, 'cs': 2, 'dog': 3, 'sk': 2, 'word': 1}
case02 - 
{'dog': 3, 'cat': 4, 'word': 1, 'cs': 2, 'sk': 2}
case03 - 
{'dog': 3, 'cat': 4, 'word': 1, 'cs': 2, 'sk': 2}
In [ ]: