자료구조는 객체가 메모리에 배정될 때 기억공간에 적재되는 구조를 의미한다.
list, tuple은 partition(칸막이)로 구분된 영역에 원소들이 순서대로 적재된다.
set, dictionary는 하나의 큰 메모리 영역에 원소들이 적재되어 순서가 보장되지 않는다.
튜플은 변경 불가능한 자료형으로 ()를 사용한다. 혹은 아무 괄호도 없이 사용한다.
인덱싱, 슬라이싱 조회는 가능하다. list보다 속도가 빠르다.
읽기전용으로 보면 된다.
TypeError: 'tuple' object doesn't support item deletion
del, remove, append 등 삭제, 수정, 추가는 불가능하다.
t1 = 1,2,3,[3,3,4] # <class 'list'> t1의 class는 tuple이다.
print(type(t1[3]))
t1[3].remove(3) # 리스트는 삭제할 수 있다.
print(t1) # (1, 2, 3, [3, 4]) # 삭제된 내용으로 나온다.
t1.remove(3) # AttributeError: 'tuple' object has no attribute 'remove'
리스트에 비해 메모리 효율적, 데이터수정이 불가능하도록 강제하는 자료형
딕셔너리와 비슷한 자료형 = map(java), hash(Ruby), JSON, Qdject
(1) 딕셔너리는 키와 값으로 이루어져있다.
키는 유일하지만(중복 불가), 값은 중복이 될 수 있다.
cm = {윤태희:182,김재겸:180,사도진:182}
dic2 = {'이름':'홍길동','나이':25,'성별':'남자','성별':'여자'}
print(dic2) # {'이름': '홍길동', '나이': 25, '성별': '여자'} 성별 남자가 사라짐
Q. key에는 문자열만 쓸 수 있나요? -> NO. 숫자도 가능하다
@ 딕셔너리는 index가 가능한가요?
불가능하다. 딕셔너리는 순서가 없다. 딕셔너리의 호출 방식은 변수명[key] 이기 때문에, 인덱스와 생긴게 같고 인덱스로 접근이 불가능하다.
리스트와 튜플은 변수명[index] / 딕셔너리는 변수명[key]
dictionary는 순차적으로 저장되는게 아니라, 키 값을 해시함수를 통해 난수로 만들어 메모리 주소를 할당한다. 하여 key값으로 찾는게 순차적으로 찾는게 아니므로 해시함수로 인덱스를 바로 찾아 가기 때문에, list보다 빠르다. -> key를 가지고 value를 검색할 때 해시 함수를 통해 index를 찾다보니 속도가 빠르다.
dic1 = {'이름':'홍길동','나이':25,'직업':'도둑','성별':'남자',2:52}
for i in dic1 :
print(i)
이름
나이
직업
성별
2 # key만 출력이 된다. value는 출력이 되지 않는다.
for i in dic1 :
print(dic1[i])
홍길동
25
도둑
남자
52 # 이렇게 value를 출력할 수 있다.
for i in dic1.values(): # 이런 방식으로 더 간단히 할 수 있다.
print(i)
dic1['직업'] = '도둑'
del del1['성별'] 삭제 된다.
key_list = dic1.keys()
value_list = dic1.values()
(1) 변수[key] -> 찾는 key가 없을 때 KeyError
(2) 변수.get(key) -> 찾는 key가 없을 때 None
Q. key, value를 바꾸려면 어떻게 해야하나요?
value 바꾸기
dic1['이름'] = '강다정'
key 바꾸는거 아직 몰라
Q. value를 통해서 key를 찾을 수는 없나요?
dict1 = {'a':1,'b':2,'c':3}
dict2 = {'a':11,'d':22,'f':44}
dict1.update(dict2)
print(dict1) # {'a': 11, 'b': 2, 'c': 3, 'd': 22, 'f': 44}
요소 검사와 반복
dict 생성방법
part = dict(key1 = 100, key2 = 200)
print(part['key1'])
print('key1' in part)
for i in part.items() : #(key,value)를 넘긴다
print(i)
단어 빈도수 구하기 : 전체 문서에서출현 빈도가 높은 단어를 분석하는 텡스트 마이닝 기법중 하나
charset = ['abc','code','band','abc','abc']
중복된 단어를 원소로 갖는다.
p1 = {}
c1 = {}
for key in participant :
p1[key] = p1.get(key,0) + 1 # get으로 가져온다. count를 안했는데 count됨
for key2 in completion :
c1[key2] = c1.get(key2,0) + 1
for 문의 요소 반복으로 사용하여 순차적으로 단어를 하나식 key의 변수로 넘겨받는다. 넘겨받은 단어를 p1의 키로 지정하고, get()함수를 이용하여 키에 해당하는 값을 꺼내온다. 이때 값이 없는 경우 0으로 초기화하고 값+1을 더해서 단어를 카운트 한다. 결국 빈셋으로 시작했지만 단어:빈도수 형태인 딕트 객체로 만들어진 것일확인할 수 있다.
dic1 = {'이름':'홍길동','나이':25,'직업':'도둑','성별':'남자'}
print(dic1.get('이름')) # 홍길동
dic1['이름'] = dic1.get('이름','서자')
print(dic1) #{'이름': '홍길동', '나이': 25, '직업': '도둑', '성별': '남자'}
dic1['이름'] = dic1.get('이름','강다니엘') # 이미 이름이있으므로 값이바뀌지않는다
print(dic1) #{'이름': '홍길동', '나이': 25, '직업': '도둑', '성별': '남자'}
dic1['신분'] = dic1.get('신분','서자')
print(dic1) #{'이름': '홍길동', '나이': 25, '직업': '도둑', '성별': '남자', '신분': '서자'}
변수명.items()
key, value를 쌍으로 튜플로 묶어서 dict 객체로전환된다.
dic1 = {'이름':'홍길동','나이':25,'직업':'도둑','성별':'남자'}
a = dic1.items()
print(a)
dict_items([('이름', '홍길동'), ('나이', 25), ('직업', '도둑'), ('성별', '남자
')])
변수명.clear()
list는 변수마다 값을 할당해서 사용하기에 어려움이 있으므로 하나의 변수로 여러개의 데이터를 관리
list는 []로 표현되며, index와 slicing을 사용할 수 있다.
(파이썬에는 list 라고 부르지만 다른 언어로는 배열이라고도 한다.)
찾는값의 인덱스를 리턴한다.
문자열은 find를 사용했으나 list에서는 find를 사용할 수 없다
AttributeError: 'list' object has no attribute 'find'
poke = ['피카츄','라이츄','파이리','꼬부기','야도란']
print(poke.index('라이츄')) #'라이츄'는 몇번째에 위치해있는가?
1
list() 함수를 쓰는 경우 단어 하나하나가 요소로 변환되고, split는 공백을 기준으로 리스트 변환된다.
구분자.join(리스트)
이러면 구분자를 기준으로 합쳐진다.
print(list(str1)) #['h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', ' ', 'p', 'y', 't', 'h', 'o', 'n']
print(str1.split()) #['hello', 'world', 'python']
print(''.join(list_str)) #helloworldpython
print(','.join(list_str)) #hello,world,python
list()
리스트로 타입을 변화시킨다.
a = 'apple'
print(list(a))
'a','p','p','l','e'
list의 길이를 구한다.
list2 = ['피카츄','라이츄','파이리','꼬부기']
print(len(list2))
리스트에서 원하는 값이 몇개있는지 센다.
print(list2.count('피카츄'))
1
지우고 싶은 위치를 알 때 : del
지우고 싶은 값을 알 때 : remove
del 사용하기
del 리스트명[인덱스]
a = [1,2,3,4,5,6,7]
del a[2]
print(a) # [1, 2, 4, 5, 6, 7]
del a[2:6]
print(a) # [1, 2]
remove 사용하기
a = [1,2,3,4,5,6,7]
a.remove(1)
print(a) # [2, 3, 4, 5, 6, 7]
del은 예약어, remove는 메소드
poke = ['피카츄','라이츄','파이리','꼬부기','야도란']
a = '야도란'
b = ['피존투','또가스']
c = '파이리'
insert 중간에 추가시킬 수 있다.
poke.insert(3,c) # ['피카츄', '라이츄', '파이리', '파이리', '꼬부기', '야도란']
print(poke)
append 맨 뒤로 값이 추가된다.
poke.append(a) # ['피카츄', '라이츄', '파이리', '파이리', '꼬부기', '야도란', '야도란']
print(poke)
extend, iterable 객체를 list에 추가할 때 사용함. 각 요소를 꺼내어 맨 뒤에 추가함
리스트 안에 리스트를 넣어야 하는데 리스트 타입으로 넣기 싫고 요소 하나씩 넣고 싶을 때
poke.extend(b)
print(poke) # ['피카츄', '라이츄', '파이리', '파이리', '꼬부기', '야도란', '야도란', '피존투
', '또가스']
extent와 +의 차이점
z = x + y는 리스트 x와 y가 합쳐져서 새로운 변수 z 객체를 생성한다.
x.extent(y)는 x에 y가 추가되어 x가 확장된것이다.
정렬은 오름차순 정렬이 기본이다. (낮은데서 높은데로 올라가는거, 1부터 101로 프듀 같은)
숫자, 문자 모두 오름차순/내림차순 정렬이 가능하다.
sort(reverse=False) : 정렬(거꾸로=아뇨) 오름차순 정렬이 기본이므로 괄호 안을 생략해도 됨(sort()
num1 = [5,4,6,3,1,2,7]
num1.sort()
print(num1) #[1, 2, 3, 4, 5, 6, 7]
sort(reverse=True) : 정렬(거꾸로=네) 내림차순 정렬
num1.sort(reverse=True)
print(num1) # [7, 6, 5, 4, 3, 2, 1]
reverser() 내림차순 함수
chlist = ['a','b','d','c','e','g','f']
chlist.reverse()
print(chlist) #['f', 'g', 'e', 'c', 'd', 'b', 'a']
pop은 맨뒤의 요소를 가져가면서, 가져간 요소를 return한다. (안받으면 안보이지)
num1 = [5,4,6,3,1,2]
num1.pop() # 2 날라감
last_value = num1.pop() # 1 날라감
print(last_value) # 1
print(num1) #[5, 4, 6, 3] pop이 두번이니까 2개 날라감
list 안에서 for 과 if 를 사용하는 문법을 말한다.
변수 = [실행문 for i in list]
1) list의 요소를 i에 꺼내온다
2) i의 값을 실행문으로 처리한다
3) 처리된 결과를 변수에 순차적으로 append 한다.
변수 = [실행문 for j in list if 조건식]
1) for 문에서 list의 원소를 j에 꺼내온다
2) j를 조건식으로 비교 판단 한다
3) 조건이 참이면 j를 실행문으로 처리한다
4) 처리된 결과를 변수에 순차적으로 append 한다.
(1) range 쓰기
list_1 = list(range(10)) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
(2) for 반복문 쓰기
list_2 = []
for i in range(10) :
list_2.append(i) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
(3) 리스트 내포로 만들기
list_3 = [j for j in range(10)] # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
홀수에다가 2를 곱한거만
list_3 = [j*2 for j in range(10) if j % 2 == 1]
print(list_3)
예시)
def solution(numbers):
answer = [i*2 for i in numbers]
return answer
:: i를 꺼내와서 곱하기 2를 실행한다.
answer를 []로 감싸주면서 자동으로 리스트가 된다.
set은 집합이라고도 부르고, index가 없고 중복이 없다.
s1 = {} 방식으로 표기한다.
list의 중복을 제거하기 위해 list를 set() 으로 형 변환 하는 작업도 많이 사용된다.
s2 = set('test')
print(s2) # {'t', 's', 'e'} 문자열이 list로 변환되어 들어가기 때문이다.
setA[0] <- 이런형태가 불가능하므로 for i in setA 방식으로 하나씩 출력
s1 = set([1,2,3,4,5])
s2 = set([4,5,6])
s3 = s1|s2 # or를 의미(합집합)
print(s3) #{1, 2, 3, 4, 5, 6}
s4 = s1.union(s2) # {1, 2, 3, 4, 5, 6}
& 는 and를 의미한다. (교집합) / s1.intersection(s2)
s5 = s1 & s2 # {4, 5
s6 = s1 - s2 # 차집합 {1, 2, 3} / s6 = s1.difference(s2)
s1.add(7) # 값 추가 {1, 2, 3, 4, 5, 7}
update() 함수를 사용할 수 있다.
s1 = set([1,2,3,4,5])
s2 = set([4,5,6])
s3 = s1.update(s2)
print(s3) 왜 그냥 쓰면 None이 뜰까요? -> 리턴값이 없는 함수 라서 그렇다.
print(s1) 을 하면 {1, 2, 3, 4, 5, 6} 정상적으로 작동된다.
삭제는 remove, discard를 사용할 수 있다.
remove는 없는 내용을 지우면 error, discard는 none을 반환한다.