이것저것 공부기록

4. 리스트, 튜플, 딕셔너리 본문

언어/Python

4. 리스트, 튜플, 딕셔너리

채도리 2020. 5. 19. 22:05

리스트

· 숫자 또는 문자로 된 값을 여러 개 저장할 수 있는 시퀀스 자료 타입

· 리스트 안에 저장된 각각의 데이터를 '항목(item)'이라고 한다.

· 리스트에서는 항목의 순서가 매우 중요!

· 시작과 끝을 표시하기 위해 대괄호 [] 사용

· 내부의 항목을 분리하기 위해 쉼표(,) 사용

· 리스트의 항목으로 어떤 유형의 데이터도 가능

· 객체, 심지어 다른 리스트도 항목으로 가질 수 있으며 항목들이 동일한 유형이 아니어도 가능하다.

· 항목이 하나도 없는 리스트도 생성 가능 ex) empty = []

** C/C++나 자바 같은 프로그래밍 언어에서는 리스트와 비슷한 개념인 배열(array)를 사용한다.

리스트는 서로 다른 데이터형도 하나로 묶을 수 있지만, 배열은 동일한 데이터형만 묶을 수 있다.

리스트 생성

리스트 이름 = [값1, 값2, 값3, ···]

list = [0, 1, 2, 3, 4, 5]

리스트 항목 추가

리스트 이름.append(값)

aa = []
aa.append(0)
aa.append(1)
aa.append(2)
aa.append(3)

print(aa) # [0, 1, 2, 3] 출력

리스트 접근

· 리스트 요소에 접근하기 위해 첨자 사용 (문자열의 첨자를 이용한 접근과 유사)

· 첨자는 0부터 시작

· 리스트 이름[시작:끝+1] → 모든 값

· 리스트 이름[첨자:] → 리스트 이름[첨자]부터 끝까지 값

· 리스트 이름[:첨자] → 처음부터 리스트 이름[첨자-1]까지 모든 값

aa = [10, 20, 30, 40]
print(aa[0:3]) # [10, 20, 30, 40] 출력
print(aa[2:4]) # [30, 40] 출력
print(aa[2:]) # [30, 40] 출력
print(aa[:2]) # [10, 20] 출력

· 음수값으로도 접근 가능

aa = [10, 20, 30, 40]
print("aa[-1]은 %d, aa[-2]는 %d" %(aa[-1], aa[-2]))
# aa[-1]은 40, aa[-2]는 30 출력

· 리스트의 항목 건너뛰며 추출

aa = [10, 20, 30, 40, 50, 60, 70]
aa[::2] # [10, 30, 50, 70] 출력
aa[::-2] # [70, 50, 30, 10] 출력
aa[::-1] # [70, 60, 50, 40, 30, 20, 10] 출력

출처: 점프 투 파이썬
출처: 점프 투 파이썬

리스트의 연산

aa = [10, 20, 30]
bb = [40, 50, 60]
print(aa + bb) # [10, 20, 30, 40, 50, 60] 출력
print(aa * 3) # [10, 20, 30, 10, 20, 30, 10, 20, 30] 출력

리스트 항목 변경

· 리스트 첨자 사용하여 그 위치의 항목 값 변경 가능

· 연속된 범위의 값도 일괄로 변경 가능

· 첨자 사용시 지정 범위 주의!

# 값 1개 변경
aa = [10, 20, 30]
aa[1] = 200
print(aa) # [10, 200, 30] 출력

# 값 2개 이상 변경
aa = [10, 20, 30]
aa[1:2] = [200, 201] # [1:2]는 결국 aa[1]과 같음
print(aa) # [10, 200, 201, 30] 출력

리스트 항목 삭제

· 항목 1개 삭제

· del 키워드에서 리스트에 첨자를 지정하지 않으면 리스트 자체 삭제

aa = [10, 20, 30]
del(aa[1])
print(aa) # [10, 30] 출력

· 항목 여러 개 삭제

aa = [10, 20, 30, 40, 50]
aa[1:4] = []
print(aa) # [10, 50] 출력

· 리스트 자체 삭제

aa = [10, 20, 30]
aa = []
print(aa) # [] 출력 / 리스트 안의 항목만 삭제
----------------------------------------------
aa = [10, 20, 30]
aa = None
print(aa) # 아무것도 출력되지 않음
----------------------------------------------
aa = [10, 20, 30]
del(aa)
print(aa) # 리스트 자체가 없기 때문에 오류 발생

리스트 조작 함수

함수 설명 사용법
append() 리스트 맨 뒤에 항목 추가 리스트명.append(값)
pop() 리스트 맨 뒤의 항목 추출하여 반환(리스트에서 해당 항목은 삭제) 리스트명.pop()
sort() 리스트의 항목 정렬 (리스트 항목 자체 정렬) 리스트명.sort()
reverse() 리스트 항목의 순서를 역순으로 정렬 리스트명.reverse()
index() 지정한 값을 찾아 해당 위치 반환 리스트명.index(찾을 값)
insert() 지정된 위치에 값 삽입 리스트명.insert(위치, 값)
remove() 리스트에서 지정한 값 삭제 (단, 지정한 값이 여러 개이면 첫번째 값만 삭제) 리스트명.remove(지울 값)
extend() 리스트 뒤에 리스트 추가 (리스트+리스트와 동일) 리스트명.extend(추가할 리스트)
count() 리스트에서 해당 값의 개수 카운트 리스트명.count(찾을 값)
clear() 리스트 내용 모두 삭제 리스트명.clear()
del() 리스트에서 해당 위치의 항목 삭제 del(리스트명(위치))
len() 리스트에 포함된 전체 항목 개수 카운트 len(리스트명)
copy() 리스트의 내용을 새로운 리스트에 복사 새 리스트 = 리스트명.copy()
sorted() 리스트의 항목 정렬 후 새로운 리스트에 대입 (원래 리스트는 상태 그대로임) 새 리스트 = sorted(리스트)

 

리스트 항목 체크

· 리스트에 어떤 특정한 값을 가진 항목의 유무를 체크할 때 in 키워드 사용

fruits = ['apple', 'banana', 'orange']

if 'tomato' in fruits:
	print('tomato는 과일입니다')
else:
	print('tomato는 과일이 아닙니다')

# tomato는 과일이 아닙니다 출력

리스트 for문 사용

· 아래 코드는 리스트의 각각의 항목을 순서대로 꺼내서 변수에 할당한 후 실행문을 반복해서 실행하는 명령

· 이때 리스트의 모든 항목을 다 순회할 때까지 반복한다.

four_seasons = ['spring', 'summer', 'fall', 'winter']
for season in four_seasons:
	print(season, end=' ')
# spring summer fall winter 출력

 


튜플

· 리스트와 비슷한 시퀀스 자료 타입

· 그러나 튜플에 항목을 할당하면 이를 바꿀 수 없다.  읽기 전용 리스트 → 메뉴 항목처럼 프로그램의 실행 시 변하지 않는 값 같은 경우에 유용

· 튜플은 괄호 ()로 생성

· 첨자와 연산자, 함수 등을 리스트와 동일하게 사용 가능함

· 튜플은 변경이 불가능하기 때문에 리스트의 append(), remove()와 같은 함수는 없다.

  → 튜플의 값을 변경하려면 새로 정의해야 한다.

tpl = (10, 20, 30)
print(tpl[1]) # 20
print(tpl[0]) # 10
tpl2 = ('a', 'b')
print(tpl+tpl2) # (10, 20, 30, 'a', 'b')
print(tpl*2) # (10, 20, 30, 10, 20, 30)

tuple = ('A', 'B')
print(tuple) # ('A', 'B')
tuple = ('a', 'b')
print(tuple) # ('a', 'b')

· 튜플은 소괄호 ()를 생략 가능하다.

· 항목이 하나인 튜플은 뒤에 쉼표(,)를 붙여서 나타낼 수 있다. → 만약 쉼표를 사용하지 않으면, 소괄호로 둘러싸인 문자열로 취급하기 때문

tt1 = 10, 20, 30
print(tt1) # (10, 20, 30)
tt2 = (10)
print(tt2) # 10
tt3 = 10
print(tt3) # 10
tt4 = 10,
print(tt4) # (10,)

튜플 삭제

· del (튜플 명)

tt1 = (10, 20, 30)
del(tt1)

 


딕셔너리

· 리스트와 비슷하지만, 순서를 따지지 않음 → 순서가 없기 때문에 첨자로 항목 선택 불가능

· 값과 관련된 ''가 존재하여 키(key)로 값(value)를 선택해서 항목을 찾는다.

· 중괄호 {} 사용, 쉼표로 구분된 키:값 쌍을 항목으로 지정하여 생성

· 유사한 객체들의 한 종류의 정보들을 저장할 경우 혹은 객체의 서로 연관된 정보들을 저장할 경우에 유용

dictionary = {키1:값1, 키2:값2, 키3:값3, ···}

· 빈 딕셔너리 생성 가능

phone_book = {}

딕셔너리 항목 추가

· 항목 추가시 대괄호 [] 사용, 대괄호 안에 첨자 대신 키가 들어간다.

(키는 보통 문자열이지만 숫자도 가능)

phone_book = {}
phone_book["홍길동"] = "010-1234-5678"
phone_book[1] = "010-1234-5678"
print(phone_book)
# {'홍길동': '010-1234-5678', 1: '010-1234-5678'}

딕셔너리 항목 접근

· 키로 특정 항목에 접근한다.

ex) value = 딕셔너리[키] or value = 딕셔너리.get(키)

phone_book = {'이순신':'010-1234-5678','홍길동':'010-1234-5679','강감찬':'010-1234-5689'}
value = phone_book['이순신']
print(value) # 010-1234-5678

value = phone_book.get('이순신')
print(value) # 010-1234-5678

딕셔너리 항목 변경

· 키에 의해 참조되는 항목에 값 할당

· 항목을 추가하는 방법과 개념적으로 유사

phone_book = {'이순신':'010-1234-5678','홍길동':'010-1234-5679','강감찬':'010-1234-5689'}

phone_book['홍길동'] = '010-1234-0000'
print(phone_book)
# {'이순신':'010-1234-5678','홍길동':'010-1234-0000','강감찬':'010-1234-5689'}

딕셔너리 키

· 딕셔너리는 첨자가 없어 범위 지정 에러가 없다.

· 키는 모두 유일해야 한다.

· 같은 키를 사용하면 마지막 값을 사용한다.

딕셔너리 키 확인

· 딕셔너리에서 특정 키가 존재하는지 확인하려면 in 키워드를 사용한다.

thisdict = {'brand':'Ford','model':'Mustang','year':1964}
if 'model' in thisdict:
    print("Yes, 'model' is one of the keys in the thisdict dictionary")
# print문 출력

딕셔너리 삭제

· del 사용하여 특정 키:값 항목 삭제 가능 → del 딕셔너리[키]

· 키 없이 del 사용하면 딕셔너리 삭제

· pop() 함수: 특정 키를 가진 항목을 빼내어 반환(원래 딕셔너리에서 키가 삭제됨) → x = 딕셔너리.pop(키)

· clear() 함수: 딕셔너리의 모든 항목 삭제

person = {'name':'James','age':22,'city':'seoul','sex':'M'}
del person['sex']
print(person)
# {'name': 'James', 'age': 22, 'city': 'seoul'} 출력

del person
print(person) # 에러 발생

dict = {'age':'20','city':'seoul'}
x = dict.pop('age')
print(x) # '20' 출력

dict.clear()
print(dict) # {} 출력

딕셔너리 키/값/항목 얻기

· 딕셔너리의 모든 키를 얻기 위해 keys() 사용

· 딕셔너리의 모든 값을 얻기 위해 values() 사용

· 딕셔너리의 모든 항목을 얻기 위해 items() 사용 → 딕셔너리의 모든 항목(키:값)이 튜플()로 반환

person = {'name':'James', 'age':22, 'city':'seoul', 'sex':'M'}

print(person.keys())
# dict_keys(['name', 'age', 'city', 'sex'])

print(person.values())
# dict_values(['James', 22, 'seoul', 'M'])

print(person.items())
# dict_items([('name', 'James'), ('age', 22), ('city', 'seoul'), ('sex', 'M')])

딕셔너리 for문

· 딕셔너리의 각 항목들을 순회하면서 출력해 보는 예제

phone_book = {'이순신':'010-1234-7777','홍길동':'010-1234-5678','강감찬':'010-1234-5679',
'신윤복':'010-1234-5681'}

for key in phone_book:
    print(key, phone_book[key])
  
for key in phone_book.keys():
	print(key, phone_book[key]) 
    
for key, value in phone_book.items():
	print(key, value)  
  
# 위의 세 가지 경우 모두 아래의 결과를 동일하게 출력
  
"""
이순신 010-1234-7777
홍길동 010-1234-5678
강감찬 010-1234-5679
신윤복 010-1234-5681 출력
"""

 


이상형 고르기 프로그램

import random # 랜덤 모듈 임포트
menu = [(1,'이상형 추가'),(2,'결정하기'),(3,'이상형 명단보기'),(4,'새로 입력하기'),
        (5,'종료')] # menu 튜플로 생성
ideal = [] # 이상형 입력 받을 변수

while True:
    for i,n in menu:
        print(i, n)
    select = int(input("번호를 입력하세요: "))
    if select == 1:
        s = input("당신의 이상형은? ")
        ideal.append(s)
    elif select == 2:
        print("당신의 이상형은", random.choice(ideal))
    elif select == 3:
        print(ideal)
    elif select == 4:
        ideal.clear()
    elif select == 5:
        break

2행에서 menu를 튜플로 만들었다는 게 이해가 안 갔는데, 내 생각이지만 리스트 안에 튜플로 각 항목을 하나씩 만들었다는 얘기인 것 같다. for문에서 i는 1, 2, 3, 4, 5의 숫자, n은 '이상형 추가', '결정하기' 등 메뉴의 항목을 지칭하는 것 같고. 

 

이렇게 출력이 세로로 깔끔하게 된다.

튜플로 menu = ("1. 이상형 추가", "2. 결정하기") 이런 식으로 만들어서 for i in menu: print(menu) 했을 때는 menu 그대로 출력되어서 보기에 좋지 않았다. 저 부분은 암기하고 있는 게 편할 듯!

전화번호부 만들기

contacts = {} # 키:값 쌍이 필요하므로 딕셔너리 사용, 빈 딕셔너리 생성

while True:
    name = input("(입력모드) 이름을 입력하시오: ") # 이름 입력받기
    if not name: # 이름 입력하지 않으며 반복문 빠져나가기
        break
    tel = input("전화번호를 입력하시오: ") # 전화번호 tel 입력받기
    contacts[name] = tel # name을 key, tel을 value로 하여 딕셔너리 contacts에 추가

while True:
    name = input("(검색모드) 이름을 입력하시오: ") # 검색모드 이름 입력받기
    if not name: # 이름 입력하지 않으면 반복문 빠져나가기
        break
    if name in contacts: # 입력한 이름이 cantacts 딕셔너리에 있으면 해당하는 값 출력
        print(name+"의 전화번호는",contacts[name]+"입니다.")
    else:
        print(name+"은 없습니다.")

끝부분에서, 입력받은 모든 것들이 다 문자열 형태이기 때문에 +와 ,를 혼용해서 써보았다. ,는 공백이 있고, +는 공백이 없다는 점을 이용해보았다. 

성적 평균 계산기

grades = {} # 과목명:점수 담을 딕셔너리 생성
cnt = 0
avr = 0
while True:
    sub = input("과목명: ")
    if not sub:
        break # 과목 이름 입력하지 않을 때까지 반복
    score = int(input("점수: "))
    grades[sub] = score

n, sum = 0, 0 # 과목 수와 점수 합계 입력할 변수
    
for k, v in grades.items():
    print(k, v)
    sum += v # 점수 누적해서 더하기(값 항목)
    n += 1 # 과목 수 카운트하기
    
print("평균은",sum/n,"입니다.")

영어 단어 암기 프로그램

import random

korean = ['사과','포도','개','고양이','시계'] # 리스트 미리 입력
english = ['apple','grape','dog','cat','clock']

while True:
    menus = [(1, "영어->한글"),(2, "한글->영어"),(3, "종료")]
    for i, n in menus:
        print(i, n)
    select = int(input("번호를 입력하세요: "))
    n = random.randrange(5) # random.randrange(i) -> 0~i-1 중에서 임의의 자연수 반환
    
    if select == 1:
        print(english[n]+"의 뜻은?")
        ans = input()
        if ans == korean[n]:
            print("네 맞습니다.")
        else:
            print("틀렸습니다.")

    elif select == 2:
        print(korean[n]+"은 영어로 무엇?")
        ans = input()
        if ans == english[n]:
            print("네 맞습니다.")
        else:
            print("틀렸습니다.")

    elif select == 3:
        break

소수 찾기 - 에라토스테네스의 체

int(input("자연수 n: "))
sieve = [True] * n # 에라토스테네스의 체를 담을 리스트, sieve 리스트를 True로 초기화

for i in range (2, n):
    if sieve[i] == True: # i가 소수인 경우
        print(i, end=' ') # 소수 출력

        for j in range (i+i, n, i): # i 이후 i의 배수들을 False 판정
            sieve[j] = False

근데 이렇게 코드를 짜면, 자연수 n에 7을 입력했다고 가정했을 때 결과값이 2 3 5 이렇게 출력된다.

7은 포함이 안되는데, 문제가 되지 않는건가? 그리고 사실 2번째 행이 뭘 나타내는지 잘 모르겠다.

'언어 > Python' 카테고리의 다른 글

[소창] 10주차 응용 실습 복습  (0) 2020.05.31
5. 함수, 파일, 모듈, 패키지  (0) 2020.05.20
3. 반복문  (0) 2020.05.19
2. 조건문  (0) 2020.05.19
1. 변수, 숫자, 문자열  (0) 2020.05.18