TIL 27. Python 리스트, 튜플, 딕셔너리

rahula·2021년 6월 3일
0

python

목록 보기
2/10
post-thumbnail

파이썬의 자료형 기초에 대해 알아보겠습니다. 이 글은 책 점프 투 파이썬을 토대로 작성됐습니다.

list

list란?

다른 언어의 array가 파이썬의 list이다. List를 사용하면 여러 값들을 순차열 적으로 저장할 수 있다.

korea_provinces = ["강원도", "경기도", "경상도", "전라도", "충청도"]

List는 위와 같이 , 즉 대괄호 안에 원하는 값들을 나열 하는 식으로 생성할 수 있으며, 각각의 값들은 쉼표를 사용해서 구분한다.
List 에 저장되어 있는 값은 element 라고 한다.

list 인덱싱

리스트도 문자열처럼 인덱싱과 슬라이싱이 가능하다. 기본적으로 인덱싱과 슬라이싱은 기존 리스트를 변경하는 게 아니라 새로운 값을 반환시키는다는 점에서 같다.
순서는 0부터 센다.

my_list = [1,2,3,4,5]
print(my_list[0]) # 1
print(my_list[0] + my_list[-1]) # 6

big_list = [1,2, [1,2,[1,2,3,4,5]]]
print(big_list[-1][-1][-1]) # 5

list 슬라이싱

list의 슬라이싱은 기본적으로 다음과 같다.

list_name[start : stop : step]

start는 시작할 위치,
stop은 멈출 위치를 뜻한다.

print(my_list[0:1]) # 1
print(my_list[0:-1]) # 1,2,3,4
print(my_list[0:])  # 1,2,3,4,5
print(my_list[:-1])  # 1,2,3,4
print(my_list[:])  # 1,2,3,4,5

그리고 step으로 몇 개씩 건어뛰어 가져올지를 결정할 수 있다.

step은 옵션이기 때문에 선언해주지 않아도 된다.
만일 선언이 안되면 default 로 1로 지정된다.

my_list = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17]

print(my_list[0:-1:2])
print(my_list[0:-1:3])
print(my_list[0:-1:4])

'''
[1, 3, 5, 7, 9, 11, 13, 15]
[1, 4, 7, 10, 13, 16]
[1, 5, 9, 13]
'''

list와 연산자

list끼리 더하기(합치기)

a = [1,2,3]
b = [4,5,6]
print(a + b) # [1,2,3,4,5,6]

list 반복하기

print(a * 3) # [1,2,3,1,2,3,1,2,3]

list의 길이 구하기

print(len(a))

len함수는 문자열, 리스트 외에도 튜플과 딕셔너리에도 사용할 수 있다.

list의 수정과 삭제

del키워드를 이용해서 list의 element를 삭제할 수 있다.

my_list = ["apple", "banana", "coconut"]
my_list[0] = "pineapple"
print(my_list) # ["pineapple", "banana", "coconut"]

del my_list[-1]
print(my_list) #  ["pineapple", "banana"]
del my_list[-1]
print(my_list) #  ["pineapple"]

리스트 관련 함수

append

append는 리스트의 마지막 인덱스에 인자로 들어간 데이터를 추가한다.

a = [1,2,3]
a.append(4) # [1,2,3,4]

sort

sort함수는 리스트의 요소를 순서대로 정렬해준다.

my_list = [6,78,2,3,56]
my_list.sort() # [2,3,6,56,78]

reverse

reverse함수는 리스트를 역순으로 뒤집어준다. sort와 달리, 요소들간의 크기에 상관없이 순서만 뒤집는다.

index

index(a)함수는 리스트에 a값이 있으면 a의 위치값을 return한다.

insert

insert(a,b)함수는 a의 위치값에 b를 삽입하는 함수이다.

remove

remove(a)는 첫번째로 나오는 a를 삭제하는 함수이다.
혹은 list내의 특정 요소를 인자값으로 넣어줌으로써 삭제하는 방법이 있다.

pop

pop()은 리스트의 맨 마지막 요소를 반환하고 그 요소를 삭제한다.

pop(a)는 리스트의 a번째 요소를 반환하고 그 요소를 삭제한다.

count

count(a)는 리스트 안에 a가 몇개 있는지 조사하여 그 개수를 돌려준다.

extend

a.extend(x)에서 x에는 리스트만 올 수 있으며 원래의 a리스트에 x리스트를 더하게 된다. a = a + x와 동일하다.

range

배열을 직접 만드는 게 아니라, 하나의 sequence를 만들어준다. 그리고 반복문으로 요소들을 배열에 집어 넣는 등의 일을 할 수 있다. 리스트를 만들고 싶다면 list함수를 쓰면 된다.

튜플

immutable : 왜 리스트 냅두고 튜플을 쓰는거야?

프로그램이 실행되는 동안 그 값이 항상 변하지 않기를 바란다거나 값이 바뀔까 걱정하고 싶지 않다면 주저하지 말고 튜플을 써야 한다.

튜플은 몇 가지 점을 제외하곤 리스트와 거의 비슷하다.

리스트는 그 값의 생성, 삭제, 수정이 가능하지만 튜플은 한 번 선언된 이상 그 값을 바꿀 수 없다.
튜플과 리스트의 가장 큰 차이는 그 값을 변화시킬 수 있는가 여부이다. 즉 리스트의 항목 값은 변화가 가능하고 튜플의 항목 값은 변화가 불가능하다.

Tuple은 일반적으로 2개에서 5개 사이의 요소들을 저장할때 사용되며, 특정 데이터를 ad hoc(즉석적으로) 하게 표현하고 싶을때 사용됩니다.

List는 수정이 가능하고 여러 수의 요소들을 저장할 수 있도록 했기때문에 tuple보다 차지하는 메모리 용량이 더 큽니다. 더 많은 기능과 flexibility를 제공하기 때문에 어쩔 수 없이 용량이 커지는거죠. 하지만 tuple은 제한적인 만큼 용량이 더 적습니다. 그래서 수정이 필요없고 간단한 형태의 데이터를 표현할때는 tuple을 사용하는게 훨씬 더 효과적입니다.

튜플에서의 list관련 함수

리스트의 함수 append, sort, reverse, insert, remove등은 튜플에서 쓸 수 없다. 항목값을 바꾸는 함수들이기 때문이다.

튜플은 한 번 할당된 이상 내부의 값은 절대 안 바뀐다.

여전히 쓸 수 있는 함수로는 항목값을 변경시키지 않는 index, count, len 등이 있다.

my_tuple.append((1,2,3))
# AttributeError: 'tuple' object has no attribute 'append'

my_tuple[0] = "lalala"
# TypeError: 'tuple' object does not support item assignment

del my_tuple[-1]
# TypeError: 'tuple' object doesn't support item deletion


my_tuple = (34,7,2,3,678)
print(my_tuple.index(678)) # 4
print(my_tuple.count(678)) # 1
print(len(my_tuple)) # 5

튜플끼리 더하거나 인덱싱, 슬라이싱을 하는 등 튜플을 참조해서 새로운 값을 만들어내는 것은 상관 없다. 즉 id(주솟값)를 바꾸는 것은 상관이 없다.

튜플 더하기와 곱하기

더하기와 곱하기도 마찬가지로 기존 튜플의 내부 항목을 바꾸는 것이 아니라 아예 새로운 데이터를 만드는 것이기 때문에 얼마든지 쓸 수 있다.

(1,2,3) + (1,2,3) 
# (1,2,3,1,2,3)


(1,2) * 3
# (1,2,1,2,1,2)

dict

다른 대부분의 언어와 마찬가지로 파이썬도 객체를 갖고 있다. 즉, key와 value를 한 쌍으로 갖는 자료형을 갖는다. 파이썬에서는 이를 딕셔너리라고 부른다.

딕셔너리는 리스트나 튜플처럼 순차적으로(sequence) 해당 요솟값을 구하지 않고 key를 통해 value를 얻는다. 이것이 딕셔너리의 가장 큰 특징이다.

my_dict = {'a':"apple", 'b':"banana", 'c':"coconut"}
my_dict['a'] == "apple" # True

dict의 key와 value

dick의 key에는 변하지 않는 값을 사용하고, value에는 변하는 값과 변하지 않는 값 모두 사용할 수 있다.

my_dict = {1:"apple", True:"banana", (1,2,3):"coconut"}
my_dict[(1,2,3)] # "coconut"

흠..직관적으로 와닿는 구조는 아니다. 언제 이렇게 쓰게 되는지 궁금하다.

dict에서 value 얻기

리스트, 튜플, 문자열은 요솟값을 얻고자 할 때 인덱싱이나 슬라이싱 기법 중 하나를 사용했다. 그러나 딕셔너리는 한 가지 방법뿐이다. Key를 사용해서 value를 구하는 방법이다.

dict이름[key]식으로 해당 key와 쌍을 이루는 value값을 얻을 수 있다.

my_dict = {'a':"apple", 'b':"banana", 'c':"coconut"}
print(my_dict['a']) # apple

dict의 쌍 추가, 삭제하기

그리고 del 키워드를 이용해서 특정 항목을 삭제할 수 있다.

my_dict = {'a':"apple", 'b':"banana", 'c':"coconut"}
my_dict['d'] = "dragonfruit"
# {'a':"apple", 'b':"banana", 'c':"coconut", 'd':"dragonfruit}

del my_dict['a']
# {'b':"banana", 'c':"coconut", 'd':"dragonfruit}

중복되는 key값이 있는 경우

딕셔너리에서 key는 단 하나만 있는 고유한 값으로 취급된다. 따라서 중복되는 key값이 있다면, 하나를 제외한 나머지 것들이 모두 무시된다는 점을 주의해야 한다. 동일한 key가 존재하면 어떤 key에 해당하는 value를 불러야 할지 알 수 없게되기 때문이다.

가장 마지막 순서에 있는 key를 제외하고 모두 무시된다.

my_dict = {'a':"apple", 'a':"banana", 'a':"coconut"}
print(my_dict['a']) # coconut

dict관련 함수

keys

keys 함수는 dict의 key들만을 모아서 dict_keys라는 객체를 돌려준다.

my_dict = {'a':"apple", 'a':"banana", 'a':"coconut"}
my_keys = my_dict.keys()
# dict_keys(['a', 'b', 'c'])

values

values 함수는 dict의 value들만을 모아서 dict_values라는 객체를 돌려준다.

my_keys = my_dict.values()
# dict_values(['apple', 'banana', 'coconut'])

왜 리스트가 아닌 객체로 줄까?

keys와 values함수가 리스트가 아닌 객체로 주는 이유는 메모리 때문이라고 한다. 리스트로 돌려주기 위해서는 메모리 낭비가 발생하는데, 파이썬 3 버전 이후에서는 메모리 낭비를 줄이기 위해 dict_keys처럼 객체를 돌려준다.

리스트를 원한다면 list함수를 사용하면 된다.

items

items함수는 key, value의 쌍을 튜플로 묶은 값을 dict_items라는 객체로 반환해준다.

my_items = my_dict.items()
dict_items([('a', 'apple'), ('b', 'banana'), ('c', 'coconut')])

clear

clear 함수는 딕셔너리 안의 모든 요소를 삭제한다.

my_dict.clear()
print(my_dict)
# {}

get

get(a)함수는 a라는 key에 대응되는 value를 반환한다.

my_dict = {'a':"apple", 'a':"banana", 'a':"coconut"}
my_a = my_dict.get('a')
print(my_a) # apple

언뜻 보면 원래 딕셔너리에서 value를 쓰기 위해 많이 쓰는 dict이름[key값]문법과 똑같다. 그러나 존재하지 않는 키로 값을 가져오려고 할 때 차이가 생긴다.

print(my_dict.get("no_such_key")) # None
print(my_dict['no_such_key']) # KeyError: 'no_such_key'

서버에서 데이터를 가져올 때와 같이, 객체에 어떤 key가 있을지 확신할 수 없을 때 사용하면 좋을 것 같다.

in 연산자

in연산자로 해당 key가 dict안에 있는지 조사할 수 있다.

print("no_such_key" in my_dict) # False

추가 질문

  1. key에는 변하지 않는 값을 사용하고, value에는 변하는 값과 변하지 않는 값 모두 사용할 수 있다고 한다. 이 말의 의미가 뭘까? 변하지 않는 데이터(immutable)를 key로 씀으로써 얻는 이점이 무엇일까?

  2. list의 변하지 않는 버전은 tuple이듯이, dict의 변하지 않는 버전은 없을까? 프로그램을 짜면서 얼마든지 dict의 내부 항목값이 바뀌지 않으리라는 보장이 없으니까.

profile
백엔드 지망 대학생

0개의 댓글