Ch1 자료구조 20-38 (자료구조5-9)

김민지·2023년 3월 20일
0
  1. 튜플(Tuple)
  • 튜플 : 리스트와 비슷하지만 아이템 변경이 불가함

    리스트 -> ['기상호, '박병찬', '성준수'] -> 아이템 변경(수정, 삭제 등) 가능
    튜플 -> ('기상호, '박병찬', '성준수') -> 아이템 변경(수정, 삭제 등) 불가능

  • 튜플 선언 : '()' 이용, 데이터 구분 ','

  • 숫자, 문자(열), 논리형 등 모든 기본 데이터를 같이 저장할 수 있음

  • 튜플에 또 다른 컨테이너 자료형 데이터를 저장할 수 있음
    ex) datas = (10, 20, 30, (40, 50, 60))

  1. 튜플 아이템 조회
  • 튜플도 리스트처럼 아이템에 자동으로 부여되는 번호표(인덱스) 존재
  • 튜플 아이템은 인덱스를 이용해서 조회 가능
students = ('박병찬', '기상호', '성준수', '허창현', '전영중')
print('students[0]: {}'.format(students[0]))    # students[0]: 박병찬
for i in range(len(students)):
    if i % 2 == 0:
        print('인덱스 짝수: students: [{}] : {}'.format(i, students[i]))
    else:
        print('인덱스 홀수: students: [{}] : {}'.format(i, students[i]))
  1. in / not in 키워드
  • 특정 아이템의 존재 유무를 알 수 있음
  • in : 있으면 True, 없으면 False
  • not in : 있으면 False, 없으면 True
studentsTuple = ('박병찬', '기상호', '성준수', '전영중', '허창현')

searchName = input('학생 이름 입력: ')

if searchName in studentsTuple:
    print('{} 학생은 우리반 학생입니다.'.format(searchName))
else:
    print('{} 학생은 우리반 학생이 아닙니다.'.format(searchName))
학생 이름 입력: 박병찬
박병찬 학생은 우리반 학생입니다.
학생 이름 입력: 최종수
최종수 학생은 우리반 학생이 아닙니다.
  • in, not in 키워드는 컨테이너 자료형뿐 아니라 문자열에서도 사용 가능 (문자열에서 특정 문자열의 존재유무 알려줌)
import random

randomNumbers = random.sample(range(1, 11), 5)  # 1~10 중 5개 랜덤추출

userNumber = int(input('숫자 입력(확률 50%): '))

if userNumber in randomNumbers:
    print('빙고!!')
else:
    print('다음 기회에')

print('randomNumbers: {}'.format(randomNumbers))
print('userNumber: {}'.format(userNumber))
숫자 입력(확률 50%): 6
빙고!!
randomNumbers: [5, 7, 9, 3, 6]
userNumber: 6
  1. 튜플 길이
  • 리스트와 마찬가지로, 튜플 길이는 튜플에 저장된 아이템 개수임
  • len() 함수 : 튜플 길이를 알려줌
  • len(), 반복문을 이용하면 튜플의 아이템 조회가 가능
students = ('박병찬', '기상호', '성준수', '전영중', '허창현')

for i in range(len(students)):
    print('i : {}'.format(i))
    print('students[{}] : {}'.format(i, students[i]))
n = 0
while n < len(students):
    print('n : {}'.format(n))
    print('students[{}] : {}'.format(n, students[n]))
    n += 1
for student in students:
    print(student)
  1. 튜플 결합
  • extend() 사용불가 (튜플은 수정 불가기 때문)
  • 덧셈 연산자(+)로 결합해 새로운 튜플 생성 가능
studentTuple1 = ('박병찬', '기상호', '정희찬')
studentTuple2 = ('최종수', '성준수', '전영중')
studentTuple3 = studentTuple1 + studentTuple2
print(studentTuple3)
myFavoriteNumbers = (1, 3, 5, 6, 7)
friendFavoriteNumbers = (2, 3, 5, 8, 10)

print('myFavoriteNumbers: {}'.format(myFavoriteNumbers))
print('friendFavoriteNumbers: {}'.format(friendFavoriteNumbers))


for number in friendFavoriteNumbers:
    if number not in myFavoriteNumbers:
        myFavoriteNumbers = myFavoriteNumbers + (number,)

print('myFavoriteNumbers: {}'.format(myFavoriteNumbers))

(number,) -> 아이템을 튜플에 바로 더할 수 없기 때문에 튜플로 만들어주고 더함

  1. 튜플 슬라이싱
  • 리스트와 마찬가지로 [n:m]을 이용 -> 원하는 아이템만 뽑아낼 수 있음
students = ('박병찬', '기상호', '성준수', '전영중', '허창현', '전영중')
print(students[2:4])      # ('성준수', '전영중')
  • 슬라이싱 할 때 단계 설정 가능
    ex) students[1:4:2] -> 2단계로 건너뛰어서 추출
  • 튜플은 슬라이싱을 이용해서 아이템 변경 불가 (튜플은 아이템 수정 불가)
  • 리스트를 튜플 아이템으로 변경 가능 (리스트로도 물론 가능)
students = ['박병찬', '기상호', '성준수', '전영중', '허창현', '최종수']

students[1:4] = ('Ki Sang Ho', 'Sung Jun Su', 'Jeon Yeong Jung')
print(students)     # ['박병찬', 'Ki Sang Ho', 'Sung Jun Su', 'Jeon Yeong Jung', '허창현', '최종수']
print(type(students))    # list 타입
  • slice() 함수 이용 -> 아이템 슬라이싱 가능
students = ['박병찬', '기상호', '성준수', '전영중', '허창현', '최종수']

print(students[slice(2, 4)])   # 2부터 3까지
print(students[slice(4)])   # 0부터 3까지
print(students[slice(2, len(students))]) # 2부터 끝까지
['성준수', '전영중']
['박병찬', '기상호', '성준수', '전영중']
['성준수', '전영중', '허창현', '최종수']
  1. 리스트와 튜플
  • 튜플은 리스트와 달리, 아이템 추가, 변경, 삭제 불가능
students.append('최종수')    # 추가
students[3] = '주찬양'       # 변경
students.pop()              # 삭제

-> 튜플 불가능, 리스트 가능

  • 튜플 선언시 괄호 생략 가능 (리스트는 불가)
students = '박병찬', '기상호', '성준수', '전영중'
print(students)             # ('박병찬', '기상호', '성준수', '전영중')
print(type(students))       # tuple
  • 리스트와 튜플은 서로 자료형 변환 가능
students = ['박병찬', '기상호', '성준수', '전영중']

students = tuple(students)     # 리스트 -> 튜플로 변환
print(students)
print(type(students))

students = list(students)      # 튜플 -> 리스트로 변환
print(students)
print(type(students))
  • 튜플 아이템을 수정(추가,변경,삭제)하려면 리스트로 변환 후 하기!
  1. 튜플 아이템 정렬
  • 튜플은 수정이 불가하기 때문에 리스트로 변환 후 정렬하기
    -> list() -> sort() or sort(reverse=True) -> tuple()
  • sorted() : 바로 튜플 정렬 가능 -> 기존 튜플이 수정되는 것이 아니라, 새로운 리스트가 생성됨
students = ('박병찬', '기상호', '성준수', '전영중', '최종수', '주찬양')
students = sorted(students)    
print(students)            # ['기상호', '박병찬', '성준수', '전영중', '주찬양', '최종수']
print(type(students))      # <class 'list'>
  1. 튜플과 for문
  • for문을 이용하면 튜플의 아이템을 자동으로 참조(조회)할 수 있음
cars = '그랜저', '소나타', '말리부', '카니발', '쏘렌토'

for i in range(len(cars)):
    print(cars[i])

for car in cars:
    print(car)
studentsCnts = (1, 19), (2, 20), (3, 22), (4, 18), (5, 21)

for classNo, cnt in studentsCnts:      # 튜플 아이템을 차례대로 조회, 순서대로 인덱스 0,1 인덱스를 조회하고 각 classNo, cnt가 됨
    print('{}학급 학생수: {}'.format(classNo, cnt))
for i in range(len(studentsCnts)):
    print('{}학급 학생수: {}'.format(studentsCnts[i][0], studentsCnts[i][1]))      # 위와 같은 결과 (좀더 번잡함)
studentsCnt = (1, 18), (2, 19), (3, 23), (4, 21), (5, 20), (6, 22), (7, 17)

sum = 0; avg = 0

for classNo, cnt in studentsCnt:
    print('{}학급 학생수: {}명'.format(classNo, cnt))
    sum += cnt

avg = sum / len(studentsCnt)

print('전체: {}명'.format(sum))
print('평균: {}명'.format(avg))
minScore = 60

scores = (
    ('국어', 58),
    ('영어', 77),
    ('수학', 89),
    ('과학', 99),
    ('국사', 50))

for item in scores:
    if item[1] < minScore:
        print('과락 과목: {}, 점수: {}'.format(item[0], item[1]))
for subject, score in scores:
    if score < minScore:
        print('과락 과목: {}, 점수: {}'.format(subject, score))
for subject, score in scores:
    if score >= minScore: continue    # 아래 실행문으로 가지않고 for문을 바로 다시 함
    print('과락 과목: {}, 점수: {}'.format(subject, score))
studentCnt = (1, 18), (2, 19), (3, 23), (4, 21), (5, 20), (6, 22), (7, 17)

minClassNo = 0; minCnt = 0
maxClassNo = 0; maxCnt = 0

for classNo, cnt in studentCnt:
    if minCnt == 0 or minCnt > cnt:
        minCnt = cnt
        minClassNo = classNo
    if maxCnt < cnt:
        maxCnt = cnt
        maxClassNo = classNo

print('학생수 가장 적은 학급: {}, 학생수: {}'.format(minClassNo, minCnt))
print('학생수 가장 많은 학급: {}, 학생수: {}'.format(maxClassNo, maxCnt))
  1. 튜플과 while문
cars = ('그랜저', '소나타', '말리부', '카니발', '쏘렌토')

n = 0
while n < len(cars):
    print(cars[n])
    n += 1

n = 0
while True:
    print(cars[n])
    n += 1    
    if n == len(cars):
        break
minScore = 60

scores = (
    ('국어', 58),
    ('영어', 77),
    ('수학', 89),
    ('과학', 99),
    ('국사', 50)
)

n = 0
while n < len(scores):

    if scores[n][1] >= minScore:
        n += 1
        continue
    print('과락 과목: {}, 점수: {}'.format(scores[n][0], scores[n][1]))
    n += 1
studentCnts = (1, 18), (2, 19), (3, 23), (4, 21), (5, 20), (6, 22), (7, 17)

minClassNo = 0; maxClassNo = 0
minCnt = 0; maxCnt = 0

n = 0
while n < len(studentCnts):
    classCnt = studentCnts[n][1]
    classNo = studentCnts[n][0]

    if minCnt == 0 or minCnt > classCnt:
        minCnt = classCnt
        minClassNo = classNo
    if maxCnt < classCnt:
        maxCnt = classCnt
        maxClassNo = classNo

    n += 1

print('학생 수가 가장 적은 학급(학생수): {}학급({}명)'.format(minClassNo, minCnt))
print('학생 수가 가장 많은 학급(학생수): {}학급({}명)'.format(maxClassNo, maxCnt))
  1. 딕셔너리
  • 딕셔너리(Dictionary) : 키(key)와 값(value)를 이용해서 자료를 관리 (인덱스가 없고 대신 키를 부여함)
  • 키는 중복이 없어야 함!(인덱스처럼) 값은 중복 가능
  • '{}'로 선언, '키:값' 형태로 아이템 정의
    ex) {키:값}
  • key, value에는 숫자, 문자(열), 논리형 뿐만 아니라 컨테이너 자료형도 올 수 있음
  • 단, key에는 변경 불가(immutable)한 데이터만 올 수 있음
    -> 변경가능한 리스트는 올 수 없음! 튜플은 가능
memInfo = {'이름':'박병찬', '메일':'byungchan99@gmail.com', '학년':3, '취미':['농구', '게임']}
  1. 딕셔너리 조회
  • 딕셔너리는 키(key)를 이용해서 값(value)을 조회함 (키를 인덱스처럼 사용)
students = {'s1':'박병찬', 's2':'기상호', 's3':'성준수', 's4':'전영중', 's5':'최종수'}

print('students[\'s1\']: {}'.format(students['s1']))
print('students[\'s2\']: {}'.format(students['s2']))
print('students[\'s3\']: {}'.format(students['s3']))
print('students[\'s4\']: {}'.format(students['s4']))
print('students[\'s5\']: {}'.format(students['s5']))
students['s1']: 박병찬
students['s2']: 기상호
students['s3']: 성준수
students['s4']: 전영중
students['s5']: 최종수
  • 존재하지 않는 키를 이용한 조회 시 에러 발생
  • get(key값) 이용해서 값(value) 조회 가능
    -> key가 없어도 에러 발생하지 않음! 'None'으로 뜸
    ex) print(students.get('s9'))
  1. 딕셔너리 추가
  • '딕셔너리이름[키(key)] = 값(value)' 형태로 아이템을 추가함
myInfo = {}

myInfo['이름'] = '박병찬'
myInfo['전공'] = '체육'
myInfo['메일'] = 'byungchan99@gmail.com'
myInfo['학년'] = 3
myInfo['주소'] = '대한민국 서울'
myInfo['취미'] = ['농구', '게임']
myInfo['주소'] = '대한민국 부산'         # 같은 키가 중복되면 원래 키에 value값이 업데이트 됨(수정)

print(myInfo)
  • 추가하려는 키가 이미 있다면 기존 값이 변경됨
studentInfo = {}

studentInfo['name'] = input('이름 입력: ')
studentInfo['grade'] = input('학년 입력: ')
studentInfo['mail'] = input('메일 입력: ')
studentInfo['addr'] = input('주소 입력: ')

print(f'studentInfo : {studentInfo}')
  • 0~10 정수에 대해 각각의 팩토리얼을 value값으로 추가하기
factorialDic = {}

for i in range(11):
    if i == 0:               # 0!=1
        factorialDic[i] = 1
    else:
        for j in range(1, i+1):     # 팩토리얼 계산
            factorialDic[i] = factorialDic[i-1] * j  # n!은 (n-1)!에 본인을 곱한 것
print(f'factorialDic : {factorialDic}')
for i in range(11):
    if i == 0:
        factorialDic[i] = 1
    else:
        factorialDic[i] = factorialDic[i-1] * i    # 위와 같은값이 나옴! 이게 더 간단
print(f'factorialDic : {factorialDic}')
  1. 딕셔너리 수정
  • '딕셔너리이름[키(key)]=값(value)' 형태로 아이템 수정
myBodyInfo = {'이름':'gildong', '몸무게':83.0, '신장':1.8}
myBMI = myBodyInfo['몸무게'] / (myBodyInfo['신장'] ** 2)

print(f'myBodyInfo: {myBodyInfo}')
print(f'myBMI: {round(myBMI, 2)}')

date = 0
while True:
    date += 1
    myBodyInfo['몸무게'] = round(myBodyInfo['몸무게'] - 0.3, 2)
    print('몸무게: {}'.format(myBodyInfo['몸무게']))
    myBodyInfo['신장'] = round(myBodyInfo['신장'] + 0.001, 3)
    print('신장: {}'.format(myBodyInfo['신장']))

    myBMI = myBodyInfo['몸무게'] / (myBodyInfo['신장'] ** 2)

    if date >= 30:
        break

print(f'myBodyInfo: {myBodyInfo}')
print(f'myBMI: {round(myBMI, 2)}')
  1. keys(), values()
  • 전체 키(key)와 값(value) 조회 가능
memInfo = {'이름':'박병찬', '메일':'byungchan99@gmail.com', '학년':3, '취미':['농구', '게임']}

ks = memInfo.keys()
print(f'ks: {ks}')
print(f'ks type: {type(ks)}')

vs = memInfo.values()
print(f'vs: {vs}')
print(f'vs type: {type(vs)}')

items = memInfo.items()
print(f'items: {items}')
print(f'items type: {type(items)}')
ks: dict_keys(['이름', '메일', '학년', '취미'])
ks type: <class 'dict_keys'>
vs: dict_values(['박병찬', 'byungchan99@gmail.com', 3, ['농구', '게임']])
vs type: <class 'dict_values'>
items: dict_items([('이름', '박병찬'), ('메일', 'byungchan99@gmail.com'), ('학년', 3), ('취미', ['농구', '게임'])])      # 아이템이 튜플로 묶여있음
items type: <class 'dict_items'>

-> list()로 변환가능

  • for문을 이용해 조회 가능
for key in ks:
    print(f'key: {key}')

for idx, key in enumerate(ks):
    print(f'idx, key: {idx}, {key}')

for value in vs:
    print(f'value: {value}')

for idx, value in enumerate(vs):
    print(f'idx, value: {idx}, {value}')

for item in items:
    print(f'item: {item}')

for idx, item in enumerate(items):
    print(f'idx, item: {idx}, {item}')
memInfo = {'이름':'박병찬', '메일':'byungchan99@gmail.com', '학년':3, '취미':['농구', '게임']}

for key in memInfo.keys():
    print(f'{key}: {memInfo[key]}')     # key값 하나로 key,value 모두 조회 가능
scores = {'kor':88, 'eng':55, 'mat':85, 'sci':57, 'his':82}
print(f'scores: {scores}')

minScore = 60
fStr = 'F(재시험)'
fDic = {}

for key in scores:               # key값만 조회됨
    if scores[key] < minScore:   # scores[key] -> value값
        scores[key] = fStr
        fDic[key] = fStr

print(f'scores: {scores}')
print(f'fDic: {fDic}')
scores: {'kor': 88, 'eng': 55, 'mat': 85, 'sci': 57, 'his': 82}
scores: {'kor': 88, 'eng': 'F(재시험)', 'mat': 85, 'sci': 'F(재시험)', 'his': 82}
fDic: {'eng': 'F(재시험)', 'sci': 'F(재시험)'}

-> 다시 보기!!!!

  1. 딕셔너리 삭제
  • del 키워드 : del과 key를 이용한 item 삭제
    ex) del 딕셔너리이름[key값]
memInfo = {'이름':'박병찬', '메일':'byungchan99@gamil.com', '학년':3, '취미':['농구', '게임']}
print(f'memInfo: {memInfo}')

del memInfo['메일']
print(f'memInfo: {memInfo}')

del memInfo['취미']
print(f'memInfo: {memInfo}')
  • pop() 함수 : 삭제한 value값 반환 가능
memInfo = {'이름':'박병찬', '메일':'byungchan99@gamil.com', '학년':3, '취미':['농구', '게임']}
print(f'memInfo: {memInfo}')

returnValue = memInfo.pop('이름')       # 삭제한 키에 해당하는 value값을 반환할 수 있음
print(f'memInfo: {memInfo}')
print(f'returnValue: {returnValue}')
print(f'returnValue type: {type(returnValue)}')

returnValue = memInfo.pop('취미')
print(f'memInfo: {memInfo}')
print(f'returnValue: {returnValue}')
print(f'returnValue type: {type(returnValue)}')
memInfo: {'이름': '박병찬', '메일': 'byungchan99@gamil.com', '학년': 3, '취미': ['농구', '게임']}
memInfo: {'메일': 'byungchan99@gamil.com', '학년': 3, '취미': ['농구', '게임']}
returnValue: 박병찬
returnValue type: <class 'str'>
memInfo: {'메일': 'byungchan99@gamil.com', '학년': 3}
returnValue: ['농구', '게임']
returnValue type: <class 'list'>
scores = {'score1':8.9, 'score2':8.1, 'score3':8.5, 'score4':9.8, 'score5':8.8}

minScore = 10; minScoreKey = ''
maxScore = 0; maxScoreKey = ''

for key in scores.keys():
    if scores[key] < minScore:
        minScore = scores[key]
        minScoreKey = key
    if scores[key] > maxScore:
        maxScore = scores[key]
        maxScoreKey = key

del scores[minScoreKey]
del scores[maxScoreKey]

print(scores)

-> 딕셔너리에 저장된 점수 중 최고,최저 점수를 삭제
-> 다시보기!!!

  1. 딕셔너리 유용한 기능
  • in, not in 키워드 : 키(key) 존재 유무 판단
memInfo = {'이름':'박병찬', '메일':'byungchan99@gmail.com', '학년':3, '취미':['농구', '게임']}

print('이름' in memInfo)       # 키값이 있으면 True, 없으면 False 출력
print('메일' in memInfo)
print('학년' not in memInfo)     # 키값이 없으면 True, 있으면 False 출력
print('취미' not in memInfo)
  • len() 함수 : 딕셔너리 길이(아이템 개수) 알려줌
print(len(memInfo))        # 4
  • clear() 함수 : 모든 아이템 삭제
memInfo.clear()
print(memInfo)          # {}
  • 특정 키,value값 삭제하기
memInfo = {'이름':'박병찬',
           '나이':25,
           '연락처':'010-1234-5678',
           '주민등록번호':'991001-1234567',
           '주소':'대한민국 서울'}

deleteItems = ['연락처', '주민등록번호']

for item in deleteItems:
    if item in memInfo:
        del memInfo[item]

print(memInfo)    # {'이름': '박병찬', '나이': 25, '주소': '대한민국 서울'}

<제로베이스 데이터 취업 스쿨>

0개의 댓글