[멋쟁이사자처럼 데이터분석] Dictionary, Set

블체·2025년 4월 6일

Notion에서 정리한 내용을 공유용으로 옮긴 내용입니다.
양식과 구성의 어색함이 있을 수 있습니다.

04/04(금) 학습내용을 바탕으로, 당일이 아닌 추후 업로드하였음


딕셔너리

자료 관리에서 리스트/튜플

  • 하나의 리스트/튜플 안에는 다른 타입도 넣을 수 있음 [10, 11.11, True, ‘안녕하세요’] 가능
  • 학생리스트 = [’홍길동’, 15, 100, ‘김길동’, 20, 90, ‘박길동’, 30, 80]
    • 이름, 나이, 국어 점수
    • 홍길동의 값을 가져오려면 3씩 끊어서 가져온다.
    • 이름 : 0부터 3씩 증가하는 순서값을 통해 가져온다.
    • 나이 : 1부터 3씩 증가하는 순서값을 통해 가져온다.
    • but 수학 점수를 추가
      • 한 사람의 값 3개씩 → 4개씩으로 변경
      • 이름, 나이, 등등의 코드도 전부 3씩 → 4씩 으로 전부 수정되어야 함
    • 하나가 빠지면
      • 한 사람 2개씩으로 바뀌고 전부 3씩 → 2씩
  • 한 리스트/튜플에는 의미가 같은 데이터만 담을 것
    • 0부터 1씩 증가하는 순서값 전부 마찬가지
    • 데이터 관리에 용이해야 하며 유지, 보수 중요
    • [21, 39, 40, 143, 2, 40, 32, 60, 140, 5, 28, …] 이면 어떤 게 키이고 어떤 게 수학 점수인지 찾기 쉽지 않음

자료 관리에서 딕셔너리

  • 이름을 통해 데이터를 관리
  • 어느 한 개체에 포함되어 있는 데이터를 하나의 딕셔너리에 담는다.
    • 학생 1명의 데이터 → 딕셔너리
    • 전체 딕셔너리 = 학생, 을 의미하는 딕셔너리 여러 개 (의미 같음) → 이걸 리스트에 담음
    • 첫 번째 학생의 3번째 정보를 줘, 가 아닌 ‘홍길동’의 ‘수학 점수’를 줘, 라고 관리해야 편리
  • 리스트는 종류별로 각각 있어야 함
    • 중국집 데이터, 병원 데이터가 섞여서

      1. 짜장면, 2. 복통, 3. 탕수육, 4. 감기 → X
    • 여러 리스트에서 첫 번째 것들 가져옴 → 첫 번째 사람의 딕셔너리

    • 여러 리스트에서 두 번째 것들 → 두 번째 사람의 딕셔너리

      → 개발자는 리스트만 관리하면 됨

  • 딕셔너리는 삽입 X (중간삽입)
    • 선입선출(적인) 순서가 중요한 아이라 중간에 삽입 X
    • 딕셔너리는 순서가 없다고 생각하는 게 편함. 부를 때도 이름으로 호출, 관리

※ 파이썬은 뒤에 뭔가 없을 때 , 을 찍어도 오류 X

생성

# 딕셔너리 생성
# 비어 있는 딕셔너리가 생성된다.
# 딕셔너리는 나중에 추가할 수 있다.
d1 = dict()
print(type(d1))
print(d1)
# 괄호를 통한 딕셔너리 생성
# 비어 있는 딕셔너리가 생성된다.
d2 = {}
print(type(d2))
print(d2)

<class 'dict'>
{}

# 관리하는 값을 지정하여 생성한다.
d3 = {
    'v1' : 100,
    'v2' : 11.11,
    'v3' : '안녕하세요',
    'v4' : [10, 20, 30],
    'v5' : (10, 20, 30),
    'v6' : {
        'a1' : 100,
        'a2' : 200
    }
}
print(d3)

{'v1': 100, 'v2': 11.11, 'v3': '안녕하세요', 'v4': [10, 20, 30], 'v5': (10, 20, 30), 'v6': {'a1': 100, 'a2': 200}}

  • 생설할 때, 이름은 꼭 문자열이 아니어도 된다.
d10 = {
    'a1' : 100,
    10 : 200,
    11.11 : 300,
    True : 400
}
print(d10['a1'])
print(d10[10])
print(d10[11.11])
print(d10[True])

불러오기 (가져오기)

# [이름] 형태로 데이터를 가져온다.
print(d3['v1'])
print(d3['v2'])
print(d3['v3'])
print(d3['v4'][0]) # 'v4' 리스트의 순서값 0번째
print(d3['v4'][1])
print(d3['v5'][0])
print(d3['v5'][1])
print(d3['v6']['a1']) # 'v6' 딕셔너리의 이름이 'a1'인 값
print(d3['v6']['a2'])
100
11.11
안녕하세요
10
20
10
20
100
200

수정/추가

# 수정
# 이름을 통해 값을 새롭게 넣어 주면 값이 수정된다.
d3['v1'] = 200

# 추가
# 없는 이름으로 값을 넣어주면 추가된다.
d3['v7'] = 5000
{'v1': 200, 'v2': 11.11, 'v3': '안녕하세요', 'v4': [10, 20, 30], 'v5': (10, 20, 30), 'v6': {'a1': 100, 'a2': 200}, 'v7': 5000}
5000

삭제

  • pop
# pop : 이름을 지정하여 이름에 해당하는 것을 전달하고 딕셔너리에서 삭제한다.
v1 = d3.pop('v1')
print(v1)
print(d3)
200
{'v2': 11.11, 'v3': '안녕하세요', 'v4': [10, 20, 30], 'v5': (10, 20, 30), 'v6': {'a1': 100, 'a2': 200}, 'v7': 5000}
  • 없는 이름 지정시 오류 발생

  • popitem

    • 순서 개념이 들어가는 요소이므로 안 쓰길 권장. 무조건 마지막 것을 알고 있다는 게 확실할 때만 사용 권장
# 딕셔너리는 순서가 없지만 제일 마지막에 추가된 요소를 
# 이름, 값의 쌍으로된 튜플로 반환하고 딕셔너리에서는 제거한다.
v2 = d3.popitem()
print(v2)
print(d3)
('v7', 5000)
{'v2': 11.11, 'v3': '안녕하세요', 'v4': [10, 20, 30], 'v5': (10, 20, 30), 'v6': {'a1': 100, 'a2': 200}}
  • del
# del 연산을 통해 삭제할 수 있다.
del d3['v2']
print(d3)

{'v3': '안녕하세요', 'v4': [10, 20, 30], 'v5': (10, 20, 30), 'v6': {'a1': 100, 'a2': 200}}

  • 없는 이름 지정시 오류 발생

  • 있는지 없는지 애매할 때 “get”으로 가져오기

  • get

# get을 통해 가져올 때 이름이 없을 경우 None 이 나온다.
v3 = d3.get('v3')
print(v3)
print(d3)

v100 = d3.get('v100')
print(v100)
안녕하세요
{'v3': '안녕하세요', 'v4': [10, 20, 30], 'v5': (10, 20, 30), 'v6': {'a1': 100, 'a2': 200}}
None
  • pop처럼 제거되는 게 아니라 그대로 남아 있음

in

  • 튜플, 리스트, 딕셔너리에서 모두 사용
    • 튜플, 리스트인 경우 주어진 값이 포함되어 있는가
    • 딕셔너리인인 경우 주어진 이름으로 저장되어 있는 값이 있는가
list1 = [10, 20, 30, 40, 50]
tuple1 = 10, 20, 30, 40, 50
dict1 = {
    'a1' : 100,
    'a2' : 200,
    'a3' : 300
}

print(10 in list1)
print(100 in list1)
print(10 in tuple1)
print(100 in tuple1)
print('a1' in dict1)
print('a100' in dict1)
True
False
True
False
True
False

결과는 T/F로

딕셔너리가 가지고 있는 함수

# 이름들을 가져온다.
name1 = dict1.keys()
# 값들을 가져온다.
value1 = dict1.values()
# (이름, 값) 형태로 되어 있는 튜플들을 가지고 있는 요소를 가져온다.
items1 = dict1.items()

print(name1)
print(value1)
print(items1)
dict_keys(['a1', 'a2', 'a3'])
dict_values([100, 200, 300])
dict_items([('a1', 100), ('a2', 200), ('a3', 300)])
# for 문 사용하기
# 리스트는 값을 추출하여 변수에 담아준다
for v1 in list1 :
    print(v1)

# 튜플은 값을 추출하여 변수에 담아준다.
for v2 in tuple1 :
    print(v2)

# 딕셔너리는 이름을 추출하여 변수에 담아준다.
for v3 in dict1 :
    print(dict1[v3]) # print(v3) 하면 키 이름인 a1, a2, a3가 나옴

set

  • 데이터를 집합으로 사용할 때 사용하는 요소
  • 중복 허용 X
  • 순서, 이름 X → 특정 데이터 지칭해서 추출하는 것 불가능
  • 사용 용도
    • 집합 연산이 필요할 때
    • 중복된 데이터를 제거할 때. 단,
      • 순서가 바뀌어도 상관없을 때
      • 오름차순, 내림차순이나 새로운 기준으로 어차피 다시 정렬할 때
  • s1 = {} → 딕셔너리로 만들어짐 → {10, 20, 30} 처럼 넣을 값 쉼표로 나열
# set은 중복을 허용하지 않는다.
s3 = {30, 20, 30, 10, 20, 30, 30, 20, 10, 5}
print(s3)

{10, 20, 5, 30}

# set은 데이터를 가져다 사용할 수 있는 방법은 다른 형태로 만들어주거나 for 문을 사용하는 것밖에는 없다.
# 이때, 순서가 어떻게 될지는 알 수 없다.
for v1 in s3 :
    print(v1)
10
20
5
30
# list, tuple -> set
list1 = [10, 20, 30, 10, 20, 30, 20, 10]
tuple1 = 10, 20, 30, 10, 20, 30, 20, 10

s1 = set(list1)
s2 = set(tuple1)
print(s1)
print(s2)

{10, 20, 30}

{10, 20, 30}

# set -> list, tuple
# 순서는 어떻게 될지 알 수 없다.
list2 = list(s1)
tuple2 = tuple(s1)
print(list2)
print(tuple2)

[10, 20, 30]

(10, 20, 30)


EX

개발할 때는
입력, 처리, 출력 부분을 나눠서 구조 잡기

# 문제

학생 정보를 출력하는 프로그램을 만든다.

학생 정보는 다음과 같이 구성된다.

학생 한 명은 이름, 나이, 국어점수, 영어점수, 수학점수로 구성된다.

첫 번째 학생 : 홍길동, 15, 90, 91, 92
두 번째 학생 : 김길동, 18, 80, 81, 82
세 번째 학생 : 최길동, 20, 70, 71, 72

출력은 다음과 같이 한다.

모든 학생들의 정보를 모두 출력한다.

각 점수별 총점과 평균을 출력한다.
전체 총점과 평균을 출력한다.
  • 구조 잡기 (입력 / 처리 / 출력)
===입력===

# 각 학생의 정보를 가지고 있는 딕셔너리를 만들어준다.
     
# 딕셔너리를 리스트에 담는다

===처리===

# 각 점수별 총점과 평균을 구한다

# 전체 총점과 평균을 구한다.

===출력===

# 모든 학생들의 정보를 출력한다.

# 각 점수별 총점과 평균을 출력한다.

# 전체 총점과 평균을 출력한다.

개인적으로 거꾸로 작업

  • 출력
    • 필요한 출력들
  • 처리
    • 어떻게 구현해야 할지 전략
  • 입력
    • 데이터 미리 준비되어 있다면 쓰기
    • 준비된 것이 없다면 사용자에게 입력 받기
# 풀이

# 각 학생의 정보를 가지고 있는 딕셔너리를 만들어준다.
studentDict1 = {
    'name' : '홍길동',
    'age' : 15,
    'korean' : 90,
    'math' : 91,
    'english' : 92
}

studentDict2 = {
    'name' : '김길동',
    'age' : 18,
    'korean' : 80,
    'math' : 81,
    'english' : 82
}

studentDict3 = {
    'name' : '최길동',
    'age' : 20,
    'korean' : 70,
    'math' : 71,
    'english' : 72
}

# 딕셔너리를 리스트에 담는다.
studentList = [studentDict1, studentDict2, studentDict3]

# 각 점수별 총점과 평균을 구한다.
koreanTotal = 0
mathTotal = 0
englishTotal = 0

for d1 in studentList :
    koreanTotal = koreanTotal + d1['korean']
    mathTotal = mathTotal + d1['math']
    englishTotal = englishTotal + d1['english']

koreanAvg = koreanTotal // len(studentList)
mathAvg = mathTotal // len(studentList)
englishAvg = englishTotal // len(studentList)

# 전체 총점과 평균을 구한다.
allTotal = koreanTotal + englishTotal + mathTotal
allAvg = allTotal // len(studentList) // 3

# 모든 학생들의 정보를 출력한다.
for s1 in studentList :
    print(f'이름 : {s1['name']}')
    print(f'나이 : {s1['age']}')
    print(f'국어점수 : {s1['korean']}')
    print(f'수학점수 : {s1['math']}')
    print(f'영어점수 : {s1['english']}')
    print()

# 각 점수별 총점과 평균을 출력한다.
print(f'국어 총점 : {koreanTotal}')
print(f'수학 총점 : {mathTotal}')
print(f'영어 총점 : {englishTotal}')
print()
print(f'국어 평균 : {koreanAvg}')
print(f'수학 평균 : {mathAvg}')
print(f'영어 평균 : {englishAvg}')
print()

# 전체 총점과 평균을 출력한다.
print(f'전체 총점 : {allTotal}')
print(f'전체 평균 : {allAvg}')
print()
이름 : 홍길동
나이 : 15
국어점수 : 90
수학점수 : 91
영어점수 : 92

이름 : 김길동
나이 : 18
국어점수 : 80
수학점수 : 81
영어점수 : 82

이름 : 최길동
나이 : 20
국어점수 : 70
수학점수 : 71
영어점수 : 72

국어 총점 : 240
수학 총점 : 243
영어 총점 : 246

국어 평균 : 80
수학 평균 : 81
영어 평균 : 82

전체 총점 : 729
전체 평균 : 81

처음 파이썬 배울 때 진짜 딕셔너리 익히느라 헷갈려했던 기억이 남
지금 가볍게 배우니 별 거 아닌 거 같은데 또 나중에 다른 거랑 합쳐지면 또 어려워서 멘붕 오겠지...
복습을 일단 열심히 해가는 걸 메인으로...

한 주 후기

일단 회고조 하면서 알게 된 게
다른 사람들이 강의중 로비에서 쓴 댓글의 8배 정도를 썼다는 것...
회고조 조원이 정해져서 조원들 검색해 봤는데, 다른 사람들은 각자의 댓글 페이지 검색이 3페이지 안팎인데 나는 26페이지였다
충격받아서 앞으로는 수업에 방해되지 않게 드립이나 댓글을 좀 줄여야겠다는 생각을 함...

그리고 확실히 간만에 8시간 수업을 들어서 그런지 체력이 못 따라오는 게 느껴짐
운동을 하든가 아무튼 체력에 신경을 써야겠다 기존처럼 복습도 하고 다른 일도 하고 하려면.

profile
벨로그 적응할 수 있을까

0개의 댓글