1. 숫자형
1)숫자형 연산자의 종류
'''
숫자형 연산자
+
-
*
/
//: 몫
% : 나머지
abs(x) : 절대값
pow(x,y) == x ** y -> x의 y제곱
'''
2) 정수의 선언 및 출력
#정수 선언
a = 7
a2 = -14
big_int = 777777777777777777777777777777
#정수 출력
print(a) # 출력: 7
print(a2) # 출력:-14
print(big_int) # 출력:777777777777777777777777777777
#타입 출력
print(type(a)) #출력:<class 'int'>
print(type(a2)) #출력:<class 'int'>
print(type(big_int)) #출력:<class 'int'>
3) 실수의 선언 및 출력
#실수 선언
b = 0.9999
b2 = 3.14456465
b3 = -5.9
b4 = 3/9
#실수 출력
print(b) # 출력:0.9999
print(b2) # 출력:3.14456465
print(b3) # 출력:-5.9
print(b4) # 출력:0.3333333333333333
#타입 출력
print(type(b)) # 출력:<class 'float'>
print(type(b2)) # 출력:<class 'float'>
print(type(b3)) # 출력:<class 'float'>
print(type(b4)) # 출력:<class 'float'>
4) 형변환
#형변환
c= 3.
d = 6
e = .7
f = 12.7
#타입출력
print(type(c),type(d),type(e),type(f)) # 출력:<class 'float'> <class 'int'> <class 'float'> <class 'float'>
print(float(d),type(float(d))) #출력:6.0 <class 'float'>
print(int(f),type(int(f))) #출력:12 <class 'int'> -> 소수부분은 절삭
print((int(True))) #출력:1 -> True:1, False:0
print(float(False)) #출력:0.0
5) 숫자형 연산
a = 7
a2 = -14
b = 0.9999
b2 = 3.14456465
#숫자형 연산
print(a+a2) # 출력:-7
print(a-a2) # 출력:21
print(a*a2) # 출력:-98
print(a/a2) # 출력:-0.5
print(a2 //a) # 출력:-2
print(a % b2) # 출력:0.7108707000000001
print(abs(a2)) # 출력:14
print(pow(a2,a)) # 출력:-105413504
print(a2 ** a) # 출력:-105413504
x,y = divmod(100,8)
print(x,y) #출력: 12 4 -> 12는 몫. 4는 나머지
6) 복소수
#complex는 복소수
print(complex(3)) #출력:(3+0j)
print(complex(False)) #출력:0j
7) math 모듈 사용
#math 모듈 사용
import math
print(math.ceil(5.1)) #출략:6 -> 부여한 값 이상의 수 중에서 가장 작은 정수
print(math.pi) #출력:3.141592653589793 ->원주율
8) 숫자함수
# 숫자형 내장함수
print(abs(-5)) #5 -> 절대값
print(pow(5,2)) #25 -> 5의 2제곱
print(max(3,12)) #12 -> 3과 12중 가장 큰 수
print(min(4,13)) #4 -> 4,13중 가장 작은 수
print(round(3.14)) #3 -> 3.14의 반올림
print(round(4.99)) #5 -> 4.99의 반올림
# 난수 사용
from random import *
print(random()) #0.0~1.0미만의 임의의 수
print(random()*10) #0.0~10.0미만의 임의의 수
print(int(random()*10)) #0~10미만의 임의의 수
print(int(random()*10)+1) #1~10이하의 임의의 수
print(randrange(1,45)) #1~45미만의 임의의 수
print(randint(1,45)) #1~45이하의 임의의 수
2.문자형
1) 문자형의 선언
str1 = "hello"
str2 = 'python'
str3 = '''
hello
python
'''
# len은 문자열의 길이, 공백포함
print(len(str1)) #출력: 5
print(len(str2)) #출력: 6
print(len(str3)) #출력: 15
# 빈 문자열 생성
str_empty = ''
str_empty2 = str()
print(type(str_empty),len(str_empty)) #출력: <class 'str'> 0
print(type(str_empty2),len(str_empty2)) #출력: <class 'str'> 0
2) escape 코드
# escape 코드
# \n: 개행
# \t: 탭
# \\: 문자
# \':문자
# \":문자
# \000:널문자
# 예시
print("I'm yj") #출력:I'm yj
print('I\'m yj') #출력:I'm yj
# Raw String -> escape 코드를 사용하지 않아도 된다.
raw_s1 = r'C:\python\project'
print(raw_s1) #출력: C:\python\project
raw_s2 = r"\\x\y\z\q"
print(raw_s2) #출력:\\x\y\z\q
# 멀티라인 입력 -> 문자열이 길 때 사용
multi_str = "multi"\
"line"\
"Test"
print(multi_str) #출력: multilineTest
3) 문자열 연산
# 문자열 연산
str_o1 = "hello"
str_o2 = "python"
str_o3 = "nice"
print(str_o1*3) #출력: hellohellohello
print(str_o1+str_o2) # 출력:hellopython
# 특정 문자가 문자열에 포함되어있는지 여부
print('n' in str_o3) #출력:True
# not은 반대의 의미
print('N' not in str_o3) #출력:True
4) 문자열 형변환
# 문자열 형변환
print(str(1),type(str(1))) #출력:1 <class 'str'>
print(str(3.14),type(str(3.14))) #출력:3.14 <class 'str'>
print(str(True),type(str(True))) #출력:True <class 'str'>
5) 문자열 함수
str_o1 = "hello"
str_o2 = "python"
str_o3 = "nice"
# 문자열 함수
# capitalize는 첫글자를 대문자로 바꿔주는 함수
print(str_o1.capitalize()) #출력:Hello
# endwith는 마지막 문자를 확인하는 함수
print(str_o2.endswith("n")) #출력:True
# replace를 문자열을 대체하는 함수
print(str_o3.replace("ce","cky"))
# sorted는 문자 하나하나를 정렬하여 리스트로 만드는 함수
print(sorted(str_o2)) #출력:['h', 'n', 'o', 'p', 't', 'y']
# split 기준문자를 기준으로 분리하는 함수
print(str_o3.split("i")) #출력:['n', 'ce']
# join 함수는 문자열을 연결하는 함수
print(str_o2.join(["I'm ", "!"])) #출력:I'm python!
# reversed는 문자열을 뒤집는 함수. 단 list로 형변환을 해야 출력이 된다.
print(list(reversed(str_o2)))
6) 슬라이싱, 아스키 코드
str_o1 = "hello"
str_o2 = "python"
str_o3 = "nice"
# 반복(시퀀스)
for i in str_o2:
print(i)
#출력:
# p
# y
# t
# h
# o
# n
# 슬라이싱
str_s1 = "Hello Python"
# 인덱스는 마지막값의 -1까지 나타남-> [0:3]일 경우 0~2까지 나옴
print(str_s1[0:5]) #출력: Hello
# [첫번째인덱스:] -> 첫번째 인덱스부터 끝까지 가져옴
print(str_s1[6:]) #출력:Python
# 마지막 인덱스의 값으로 문자열의 길이로 지정해도 된다.
print(str_s1[:len(str_s1)]) #출력:Hello Python
print(str_s1[:len(str_s1)-1]) #출력:Hello Pytho
# [첫번째 인덱스: 마지막인덱스: 단위] ->[1:4:2]라면 1부터 3까지 가져오되 2칸 단위로 가져와라는 뜻
print(str_s1[1:4:2]) #출력:el
print(str_s1[::2]) #출력:HloPto
# 인덱스값에 음수가 들어간다면 마지막 문자열부터 좌측으로 인덱스만큼이 첫번재 인덱스가 된다.
print(str_s1[-5:]) #출력:ython
print(str_s1[1:-2]) #출력:ello Pyth
# 단위 음수가 들어간다면 역으로 출력된다.
print(str_s1[::-1]) #출력:nohtyP olleH
# 아스키 코드
a = 'z'
# ord는 알파벳을 아스키코드로 보여주는 함수
print(ord(a)) #출력:122
# chr는 아스키코드를 알파벳으로 보여주는 함수
print(chr(122)) #출력:z
3.리스트
1) 선언
#선언
a=[]
b= list()
c=[1,2,3,4]
d= [10,20.0,'aa',['a','b',3],True] # 여러개의 변수타입을 혼합해서 리스트를 구성하는 것이 가능하다.
print(a) #출력: []
print(b) #출력: []
print(c) #출력:[1, 2, 3, 4]
print(d) #출력:[10, 20.0, 'aa', ['a', 'b', 3], True]
2) 인덱싱, 슬라이싱
#인덱싱
print(type(d[1])) #출력:<class 'float'>
print(d[0]+d[1]) #출력:30.0 -> 정수와 실수를 더하면 정수값은 실수로 형 변환이 된다.
print(str(d[1])+d[2]) #출력:20.0aa -> 정수 또는 실수와 문자열을 더하려면 정수 또는 실수의 타입을 String 타입으로 변환해줘야한다.
print(d[-1]) #출력:True
print(d[3][1]) #출력:b
print(list(d[-2][1])) #출력: ['b'] -> 리스트 형태로 출력
#슬라이싱
print(d[0:3]) #출력:[10, 20.0, 'aa']
print(d[2:]) #출력:['aa', ['a', 'b', 3], True]
print(d[-2][0:3]) #출력:['a', 'b', 3]
3) 리스트 연산 & id
#리스트 연산
print(c+d) #출력:[1, 2, 3, 4, 10, 20.0, 'aa', ['a', 'b', 3], True]
print(c*3) #출력:[1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]
print("hhhh"+d[2]) #출력:hhhhaa
print(c==c[:3]+c[3:]) #출력:True->c[:3]+c[3:]는 c와 내부구조가 동일하다.
#id
temp = c
print(temp,c) #출력:[1, 2, 3, 4] [1, 2, 3, 4]
print(id(c),id(temp)) #출력:2719800378880 2719800378880 -> id값이 동일하다.
4) 리스트 수정& 삭제(함수 포함)
c=[1,2,3,4]
d= [10,20.0,'aa',['a','b',3],True]
#리스트 수정,삭제
c[0] = 4
print(c) #출력:[4, 2, 3, 4] -> 1대신에 4가 들어감
c[1:2] = ['q','s','r']
print(c) #출력:[4, 'q', 's', 'r', 3, 4] 2 대신에 q,s,r이 들어감
c[2:3] = [[4,5,6]]
print(c) #출력:[4, 'q', [4, 5, 6], 'r', 3, 4] ->s 대신 [4,5,6] 리스트가 들어감
c[1:3] = []
print(c) #출력:[4, 'r', 3, 4] -> q,[4,5,6]이 제거 ->일반적으로 사용x
del c[2]
print(c) #출력:[4, 'r', 4] ->3제거 -> 주로 사용
aa = [3,24,35,42,5,60]
print(aa) #출력:[3, 24, 35, 42, 5, 60]
aa.append(7) #append는 마지막에 값을 추가
print(aa) #출력:[3, 24, 35, 42, 5, 60, 7]
aa.sort()
print(aa) #출력:[3, 5, 7, 24, 35, 42, 60]
aa.reverse() #순서를 역순으로 나열하는 함수
print(aa) #출력:[60, 42, 35, 24, 7, 5, 3]
print(aa.index(60)) #출력:0 -> 값에 대한 인덱스값을 반환
aa.insert(2,7) # insert(index,value)형식으로 삽입
print(aa) #출력:[60, 42, 7, 35, 24, 7, 5, 3]
aa.remove(35) #remove(value)로 제거
print(aa) #출력:[60, 42, 7, 24, 7, 5, 3] -> 35제거
aa.pop()
print(aa) #출력:[60, 42, 7, 24, 7, 5] -> 마지막값인 3제거
print(aa.count(5)) #출력:1 ->list에서 value의 개수를 구하는 함수 -> 5의 개수는 한개
ex=[10,12]
aa.extend(ex) #extend함수는 끝에 값을 추가하는 함수
print(aa) #출력:[60, 42, 7, 24, 7, 5, 10, 12]
while aa:
data = aa.pop() # 끝부분의 값을 꺼내오는 방식으로도 사용가능
print(data)
# 출력:
# 12
# 10
# 5
# 7
# 24
# 7
# 42
# 60
ee = [1,5,3,78,9,10]
print(ee) #출력:[1, 5, 3, 78, 9, 10]
ee.clear() #clear는 리스트 내용을 모두 지우는 함수
print(ee) #출력:[]
5) 리스트 언팩킹
x,y,*rest = range(10)
print(x,y,rest) #출력: 0 1 [2, 3, 4, 5, 6, 7, 8, 9] -> 언팩킹은 한번에 3개까지 가능, 따라서 x,y값을 부여하고 나머지는 팩킹해서 출력
x,y,*rest =range(2)
print(x,y,rest) # 출력: 0 1 [] -> 값이 두개이므로 x,y에 값을 부여하고 rest는 빈값을 부여
x,y,*rest = 1,2,3,4,5
print(x,y,rest) # 출력:1 2 [3, 4, 5]
6) 리스트 사용시 주의해야 할 점
marks1 = [['~']*5 for _ in range(5)] # 반복으로 내부 리스트를 새로 생성
marks2 = [['~']*5]*5 # 내부 리스트의 복사
print(marks1,id(marks1)) #출력: [['~', '~', '~', '~', '~'], ['~', '~', '~', '~', '~'], ['~', '~', '~', '~', '~'], ['~', '~', '~', '~', '~'], ['~', '~', '~', '~', '~']] 2827627664896
print(marks2,id(marks2)) #출력: [['~', '~', '~', '~', '~'], ['~', '~', '~', '~', '~'], ['~', '~', '~', '~', '~'], ['~', '~', '~', '~', '~'], ['~', '~', '~', '~', '~']] 2827627663872
# 위 두개의 값은 모양은 동일하나 다른값임
marks1[0][1] = "A"
marks2[0][1] = "A"
print(marks1) # 출력: [['~', 'A', '~', '~', '~'], ['~', '~', '~', '~', '~'], ['~', '~', '~', '~', '~'], ['~', '~', '~', '~', '~'], ['~', '~', '~', '~', '~']]
print(marks2) # 출력: [['~', 'A', '~', '~', '~'], ['~', 'A', '~', '~', '~'], ['~', 'A', '~', '~', '~'], ['~', 'A', '~', '~', '~'], ['~', 'A', '~', '~', '~']]
# 위 두개의 값이 달라지는 이유는 marks1의 내부요소의 id값은 전부 다르지만 marks2의 내부요소의 아이디값은 동일하기 때문
# 아래 예시로 자세히 확인
print([id(s) for s in marks1]) #출력: [2877678819008, 2877678818816, 2877678818752, 2877678818560, 2877678818496] -> 내부 id값이 전부 다름
print([id(s) for s in marks2]) #출력: [2877678818368, 2877678818368, 2877678818368, 2877678818368, 2877678818368] -> 내부 id값이 전부 동일
4. 튜플
튜플(Tuple)은 리스트와 비슷한 자료 구조이지만, 한 번 생성된 후에 변경할 수 없는 불변(Immutable)형 자료구조입니다. 튜플은 괄호로 묶거나 괄호 없이 여러 요소를 쉼표로 구분하여 생성할 수 있습니다.
다만 튜플이 리스트보다 좋은점이 몇가지 있습니다
불변성(Immutable): 튜플은 한 번 생성되면 요소를 추가, 삭제, 변경할 수 없습니다. 이러한 불변성은 데이터의 안정성을 보장하고 의도하지 않은 변경을 방지하는데 도움을 줍니다. 데이터가 변경되면 안되는 경우에 튜플을 사용하여 안전성을 확보할 수 있습니다.
속도: 튜플은 리스트보다 속도가 빠릅니다. 튜플은 변경할 수 없기 때문에 리스트보다 더 단순하고 빠른 연산을 수행할 수 있습니다. 특히, 데이터가 변경되지 않고 읽기 전용으로 사용될 때 튜플은 더 빠른 처리 속도를 제공합니다.
메모리 사용량: 튜플은 리스트보다 메모리를 더 적게 사용합니다. 리스트는 동적으로 크기가 변하고 요소의 추가/삭제가 가능하기 때문에 메모리를 더 많이 사용하는 반면, 튜플은 불변성으로 인해 메모리를 더 효율적으로 사용할 수 있습니다.
딕셔너리의 키로 사용 가능: 튜플은 딕셔너리의 키로 사용될 수 있지만, 리스트는 딕셔너리의 키로 사용될 수 없습니다. 이는 튜플의 불변성으로 인해 키의 해시 값이 변하지 않기 때문에 가능합니다.
1) 선언
#선언
a= ()
b = (1,) #한개의 값만 들어갈 경우 반드시 콤마(,)를 입력해야 튜플로 인식한다.
c= (100,10.0,"aa","bb",("cc","dd"))
d = 10,20,30, # 튜플에서 괄호는 생략가능하다.
print(type(a),type(b),type(c),type(d)) #출력:<class 'tuple'> <class 'tuple'> <class 'tuple'> <class 'tuple'>
print(c) #출력:(100, 10.0, 'aa', 'bb', ('cc', 'dd'))
print(d) #출력:(10, 20, 30)
2) 인덱싱 & 슬라이싱
#인덱싱
print(c[1]) #출력:10.0
print(c[0]+c[1]) #출력:110.0
print(str(c[0])+c[2]) #출력:100aa
print(c[-1]) #출력:('cc', 'dd')
print(c[-1][1]) #출력:dd
print(list(c[-1])) #출력: ['cc', 'dd'] ->list로 형변환
#슬라이싱
print(c[0:3]) #출력:(100, 10.0, 'aa')
print(c[3:]) #출력:('bb', ('cc', 'dd'))
print(c[-1][1:]) #출력:('dd',)
3) 튜플 연산
b = (1,) #한개의 값만 들어갈 경우 반드시 콤마(,)를 입력해야 튜플로 인식한다.
c= (100,10.0,"aa","bb",("cc","dd"))
d = 10,20,30, # 튜플에서 괄호는 생략가능하다.
#튜플 연산
print(b+c) #출력:(1, 100, 10.0, 'aa', 'bb', ('cc', 'dd'))
print(c*2) #출력:(100, 10.0, 'aa', 'bb', ('cc', 'dd'), 100, 10.0, 'aa', 'bb', ('cc', 'dd'))
4) 튜플 함수
#튜플 함수
a = (4,5,32,8,32,11,8)
print(a) #출력:(4, 5, 32, 8, 32, 11, 8)
print(a.index(11)) #출력: 5 -> value에 대한 index값 출력
print(a.count(8)) #출력: 2 -> 튜플에 8은 두개존재
5) 팩킹 & 언팩킹
#팩킹 & 언팩킹
d = ('ssss','ddddd','bbbbb','cccc') #팩킹 -> 선언과 동일
(a1,a2,a3,a4) = d #a1~a4까지의 값은 변수로 선언을 하지 않았지만 오류가 나지 않는다. -> 변수가 뒤로 와야한다.
#튜플값을 분리하는 것을 언팩킹이라 한다.
print(type(a1),type(a2),type(a3),type(a4)) #출력:<class 'str'> <class 'str'> <class 'str'> <class 'str'>
print(a1) #출력:ssss
print(a2) #출력:ddddd
print(a3) #출력:bbbbb
print(a4) #출력:cccc
#divmod함수는 앞의 숫자를 뒤의 숫자로 나눠서 몫과 나머지를 출력하는 함수
print(divmod(100,9)) #출력 : (11, 1)
#언팩킹
print(divmod(*(100,9))) #출력 : (11, 1)
print(*(divmod(100,9))) #출력: 11 1
5. 딕셔너리(사전)
파이썬 사전(Dictionary)은 키(Key)와 값(Value)으로 이루어진 자료 구조입니다. 각 키와 값은 쌍(pair)으로 연결되어 있으며, 키를 통해 해당하는 값을 빠르게 찾을 수 있습니다. 사전은 중괄호({})를 사용하여 생성하며, 키와 값은 콜론(:)으로 구분하여 지정합니다. 또한 json형태와 동일합니다.
1) 선언
a = {'name':'yj','age':30,'hobby':'python'} #딕셔너리는 key:value로 이루어짐
b = {0:'zero'}
c = {'arr':[54,21,58,8]}
d = {
'Fruit':'grape',
'City':'seoul',
'Number':30,
'Boolean':True
}
e = dict([
('Fruit','grape'),
('City','seoul'),
('Number',30),
('Boolean',True)
])
f = dict(
Fruit = 'grape',
City='seoul',
Number=30,
Boolean=True
)
print(d==e==f) #출력:true ->d,e,f는 동일함
print(type(a),a) #출력:<class 'dict'> {'name': 'yj', 'age': 30, 'hobby': 'python'}
print(type(b),b) #출력:<class 'dict'> {0: 'zero'}
print(type(c),c) #출력:<class 'dict'> {'arr': [54, 21, 58, 8]}
print(type(d),d) #출력:<class 'dict'> {'Fruit': 'grape', 'City': 'seoul', 'Number': 30, 'Boolean': True}
print(type(e),e) #출력:<class 'dict'> {'Fruit': 'grape', 'City': 'seoul', 'Number': 30, 'Boolean': True}
print(type(f),f) #출력:<class 'dict'> {'Fruit': 'grape', 'City': 'seoul', 'Number': 30, 'Boolean': True}
print(a['name']) #출력:yj -> key가 없을 시 에러발생
print(a.get('name')) #출력:yj -> key가 없을 시 None -> 안전하기 때문에 주로 사용
print(b[0]) #출력:zero
print(b.get(0)) #출력:zero
print(f.get('City')) #출력:seoul
2) 수정
# 변수는 앞에서 선언한것을 사용
a['addr'] = "마포" # key가 없을 때는 추가 됨
print(a) #출력:{'name': 'yj', 'age': 30, 'hobby': 'python', 'addr': '마포'}
a['age'] = 50 # key가 있을 때는 수정됨
print(a) #출력:{'name': 'yj', 'age': 50, 'hobby': 'python', 'addr': '마포'}
a['rank'] = [1,2,3]
print(a) #출력: {'name': 'yj', 'age': 50, 'hobby': 'python', 'addr': '마포', 'rank': [1, 2, 3]}
3) 딕셔너리 함수
# 변수는 앞에서 선언한것을 사용
print(len(a)) #출력: 5 ->key의 개수가 출력
# keys 함수는 key값만 출력, values 함수는 value값만 출력
print(a.keys()) #출력:dict_keys(['name', 'age', 'hobby', 'addr', 'rank']) ->key값들만 가져옴
print(b.keys()) #출력:dict_keys([0])
print(c.keys()) #출력:dict_keys(['arr'])
print(d.keys()) #출력:dict_keys(['Fruit', 'City', 'Number', 'Boolean'])
print(e.keys()) #출력:dict_keys(['Fruit', 'City', 'Number', 'Boolean'])
print(f.keys()) #출력:dict_keys(['Fruit', 'City', 'Number', 'Boolean'])
print(list(a.keys())) #출력:['name', 'age', 'hobby', 'addr', 'rank']
print(a.values()) #출력:dict_values(['yj', 50, 'python', '마포', [1, 2, 3]])
print(b.values()) #출력:dict_values(['zero'])
print(list(a.values())) #출력:['yj', 50, 'python', '마포', [1, 2, 3]]
print(a.items()) #출력:dict_items([('name', 'yj'), ('age', 50), ('hobby', 'python'), ('addr', '마포'), ('rank', [1, 2, 3])])
print(list(a.items())) #출력:[('name', 'yj'), ('age', 50), ('hobby', 'python'), ('addr', '마포'), ('rank', [1, 2, 3])]
print(a.pop('name')) #출력: yj
print(a) #출력:{'age': 50, 'hobby': 'python', 'addr': '마포', 'rank': [1, 2, 3]} ->name의 key와 value가 삭제됨
print(a.popitem()) #출력:('rank', [1, 2, 3]) -> 마지막의 key와 value를 가져온다.
print(a) #출력:{'age': 50, 'hobby': 'python', 'addr': '마포'}
print('age' in a) #출력 True -> Key값을 찾는 함수
print(50 in a) #출력: False -> value는 있지만 key가 없기 때문에 False
a.update(age=36) #key=value로 수정
print(a) #출력:{'age': 36, 'hobby': 'python', 'addr': '마포'}
temp = {'hobby':'java'}
a.update(temp) # 딕셔너리로 수정
print(a) #출력:{'age': 36, 'hobby': 'java', 'addr': '마포'}
4) Dict Setdefault
#튜플 -> 딕셔너리
dict_a = {}
dict_b = {}
# Setdefault 미사용
for k,v in tuple_a:
if k in dict_a:
dict_a[k].append(v)
else:
dict_a[k] = [v]
print(dict_a) #출력: {'k1': ['val1', 'val2'], 'k2': ['val3', 'val4', 'val5']}
# Setdefault 사용
for k,v in tuple_a:
dict_b.setdefault(k,[]).append(v) #setdefault(key, value타입) -> 여기서는 value가 list로 담기기 때문에 append 사용가능
print(dict_b) #출력: {'k1': ['val1', 'val2'], 'k2': ['val3', 'val4', 'val5']}
5) 불변 딕셔너리
from types import MappingProxyType
d = {'k1':'val1'}
# Read Only
d_frozen = MappingProxyType(d)
print(id(d),d) # 출력:1962933642752 {'k1': 'val1'}
print(id(d_frozen),d_frozen) #출력:1962935115728 {'k1': 'val1'}
# 수정 가능
d['k2'] = 'val2'
print("d=",d,"d_frozen=",d_frozen) #출력:d= {'k1': 'val1', 'k2': 'val2'} d_frozen= {'k1': 'val1', 'k2': 'val2'}
#수정 불가
d_frozen['k2'] = 'val22' # 에러발생 : TypeError: 'mappingproxy' object does not support item assignment
출력 내용을 보시면 불변 딕셔너리를 만들기 전 원래 변수를 변경하면 불변 딕셔너리의 값도 수정이 됩니다. 불변 딕셔너리로 만든 변수를 직접 수정하려고 했을 때만 수정이 안되는 것이니 주의해야 합니다.
6.집합(set)
집합은 중복을 허용하지 않고 순서를 보장하지 않는 것이 특징입니다. 그리고 순서가 없기 때문에 인덱스를 사용하여 요소에 접근할 수 없습니다.
1) 선언
a = set()
b = set([5,6,9,25])
c = set(['2',30,'aa','dd'])
d = {'abc','def','ghi'}
e = {11,'das',(4,5,6),3.444}
f = {1,1,1,5,6,6}
print(a,type(a)) #출력:set() <class 'set'>
print(b,type(b)) #출력:{9, 5, 6, 25} <class 'set'> -> set은 순서롤 보장하지 않는다.
print(c,type(c)) #출력:{'2', 'aa', 30, 'dd'} <class 'set'>
print(d,type(d)) #출력:{'ghi', 'abc', 'def'} <class 'set'>
print(e,type(e)) #출력:{11, 'das', 3.444, (4, 5, 6)} <class 'set'>
print(f,type(f)) #출력:{1, 5, 6} <class 'set'> -> 중복을 허용하지 않음
2) 형변환
#집합 -> 튜플
t = tuple(b)
print(type(t),t) #출력:<class 'tuple'> (9, 5, 6, 25)
#집합 -> 리스트
l = list(f)
print(type(l),l) #출력:<class 'list'> [1, 5, 6]
3) 집합관련 함수
s1 = {10,52,13,45,8,1}
s2 = {10,13,8,5,22,4}
# 교집합
print(s1 & s2) #출력:{8, 10, 13}
print(s1.intersection(s2)) #출력:{8, 10, 13}
#합집합
print(s1 | s2) #출력:{1, 4, 5, 8, 10, 45, 13, 52, 22}
print(s1.union(s2)) #출력:{1, 4, 5, 8, 10, 45, 13, 52, 22}
#차집합
print(s1-s2) #출력:{1, 52, 45}
print(s1.difference(s2)) #출력:{1, 52, 45}
# 중복확인 ->중복되는 값이 있으면 False, 없으면 True
print(s1.isdisjoint(s2)) #출력: False
#부분집합인지 확인
s3 = {10,52,45}
#아래 두개의 값은 동일, 단 부분이 되는 집합의 위치만 바뀜
print(s3.issubset(s1)) #출력:True
print(s1.issuperset(s3)) #출력:True
s1.add(5)
print(s1) # 출력:{1, 45, 52, 5, 8, 10, 13} -> 5 추가 되었지만 순서는 보장X
s1.remove(45) # 없는 값을 제거하려고 할 경우 에러발생
print(s1) #출력:{1, 52, 5, 8, 10, 13} -> 45 제거
s1.discard(52) # 없는 값을 제거하려고 할 경우에도 에러 발생하지 않음
print(s1) #출력:{1, 5, 8, 10, 13} ->52제거
s1.clear() #모두 제거
print(s1) #출력:set()
4) 불변 집합
s1 = {'aa','bb','aa','bb','cc'}
s2 = frozenset(s1)
print(type(s1),s1) # 출력: <class 'set'> {'bb', 'cc', 'aa'}
print(type(s2),s2) # 출력: <class 'frozenset'> frozenset({'bb', 'cc', 'aa'})
s1.add('dd')
print("set=",s1,"frozen_set=",s2) #출력: set= {'bb', 'cc', 'aa', 'dd'} frozen_set= frozenset({'bb', 'cc', 'aa'})
# frozenset은 추가 불가
# s4.add('dd') # 에러 AttributeError: 'frozenset' object has no attribute 'add'
불변 딕셔너리와는 다르게 원본의 데이터를 변경해도 불변 집합의 값은 변하지 않는 것을 볼 수 있습니다.
5) 선언 최적화
# 파이썬 인터프리터는 바이트 코드를 실행
from dis import dis
print("--------")
print(dis('{5}')) # 과정이 짧기 때문에 더 빠르다고 볼수있음 -> set 선언시 아래방법보다 이 방법을 사용하는 것이 좋음
#출력:
# 1 0 LOAD_CONST 0 (5)
# 2 BUILD_SET 1
# 4 RETURN_VALUE
# None
print("-------")
print(dis('set([5])'))
#출력:
# 1 0 LOAD_NAME 0 (set)
# 2 LOAD_CONST 0 (5)
# 4 BUILD_LIST 1
# 6 CALL_FUNCTION 1
# 8 RETURN_VALUE
# None
'PYTHON Programming > Python' 카테고리의 다른 글
[python] 컴프리헨션 (0) | 2024.04.23 |
---|---|
[python] 반복문 (0) | 2024.04.23 |
[python] 제어문 (0) | 2024.04.22 |
[python] 변수 및 연산자 (0) | 2024.04.22 |
파이썬 설치 (0) | 2024.04.22 |