Python/파이선과 친해지기

[Python] - Python과 친해지기-DICTIONARY와 SET

우리는 아직 이 직장에서 탈출하지 못했고, 교실 관리 프로그램의 개발자로 일하고 있다. 우리의 교실에는 "김철수", "윤철수" 등 다양한 개성의 학생들이 있지만, 이번에 새로운 전학생을 받게 되었다. 그런데 이런! 새 학생의 이름이 "김철수"이다. 

>> students=["김철수","윤철수","박철수"]
## 이렇게 잘살고 있는 철수교실에

>> students.append("김철수")
## 한명의 김철수가 더 들어오게 된다.

>> print(students)
["김철수","윤철수","박철수","김철수"]

문제가 있다. 우리는 공부를 잘하는 기존의 김철수와 공부를 못하는 김철수의 점수를 프로그램이 헷갈려하는 결과를 주고 싶지 않다. DB를 배운 사람이라면 당연하게 알 수 있는 문제이지만, 유일성을 부여할 수 있는 번호가 필요하다 (가령 학생 번호, 사원번호나 사람의 경우 주민번호가 될 수 있겠다.) 

 

아 좋다! 2차원 배열이 있었다. 그래서 자신있게 [학생 번호, 학생 이름]의 배열을 students에 추가하기로 하였다.

>> students=list()

>> students.append([1,"김철수"])

>> students.append([2,"윤철수"])

>> students.append([3,"박철수"])

>> students.append([4,"김철수"])

>> print(students)
[[1,"김철수"],[2,"윤철수"],[3,"박철수"],[4,"김철수"]]

뭐 좋다.  이렇게 관리해도 되지만 조금 더 안정적인 유일성 부여방법이 Python엔 존재한다.(이런 경우 휴먼에러로 4번이 중복 등록될 수도 있다.) 그 자료구조가 Dictionary 다른 말로는 Dict라고 한다.


Dictionary의 정의와 사용

Dictionary란 Key의 중복을 허용하지 않는 Key, Value 형태의 순서없는 자료구조이다.  생성은 [Dict로 사용할 변수명] = dict()로 생성하거나 문법적으로 {Key1 : Value1, Key2 : Value2 ... }을 사용하여 초기화까지 할 수 있다.

 

Key와 Value 

Dict에서 특정한 Value는 Key를 통해서만 얻을 수 있다.

>> students={1:"김철수",2:"윤철수",3:"박철수",4:"김철수"}

>> print(student[1])
"김철수"

>> print(student[3])
"박철수"

특이한점은 LIST와 다르게 대괄호[] 안에 들어가는 값이 인덱스가 아니라는 점이다.(0에서 시작하는 그 값들이 아니다! Dict는 순서가 없는 자료구조라는 걸 기억하자) 대괄호 안에 들어가는 값은 Key이며 그 Key에 상응하는 Value가 리턴이 된다는 특징이 있다. 

 

또한 변화하지 않는 값이라면 Key로 사용할 수 있다. 이게 무슨 소리냐

>> students={"학생1":"김철수","학생2":"윤철수","학생3":"박철수","학생4":"김철수"}

>> print(student["학생1"])
"김철수"

>> print(student["학생3"])
"박철수"

이것도 된다는 이야기이다. 변화하지 않는 값이기에 값을 추가 / 삭제할 수 있는 LIST는 Dictionary의 Key로 사용할 수 없다. 잘 알아두자 

>> students={["학생1"]:"김철수","학생2":"윤철수","학생3":"박철수","학생4":"김철수"}
## 이건 안된다!

다음은 자주사용되는 DICT의 메서드(함수)이다.

[DICT의 변수명].clear() : DICT의 초기화

[DICT의 변수명].items() : DICT의 (key, value) 쌍을 복사한다.

[DICT의 변수명].keys() : DICT의 Key들을 LIST로 반환한다.(정말로 LIST로 사용하려면 LIST()로 캐스팅 필요)

[DICT의 변수명].value() : DICT의 Value들을 LIST로 반환한다.(정말로 LIST로 사용하려면 LIST()로 캐스팅 필요)

>> students={"학생1":"김철수","학생2":"윤철수","학생3":"박철수","학생4":"김철수"}

>> students.items()
dict_items([('학생1', '김철수'), ('학생2', '윤철수'), ('학생3', '박철수'), ('학생4', '김철수')])

>> students.keys()
dict_keys(['학생1', '학생2', '학생3', '학생4'])

>> students.values()
dict_values(['김철수', '윤철수', '박철수', '김철수'])

>> students.clear()
>> print(students)
{}

* 여담으로 dict으로 정의된 students를 강제로 list(students)해서 강제로 list로 캐스팅하면 key만 list로 바뀐다.

* dict에 새로운 아이템을 추가하는 방법은 새로운키로 변수를 저장하면 된다. (ex : students["학생5"] = "심철수")


SET의 정의와 사용

SET란 Python 2.3부터 지원하는 기능이며, 집합 연산을 수월히 처리하기 위해 생성된 자료구조이다. Dictionary와 비슷하게 중복을 허용하지 않으며, 순서가 없지만 Value 만 존재하는 것이 특징이다.  [SET로 사용할 변수명] = set()로 빈 SET자료구조를 만들 수도 있고, 문법적으로 {1,2,3,4}로 해서 초기화까지 할 수 있다.

>> my_set={4,3,2,1}

>> print(my_set)
{1,2,3,4}

>> a="hello"
>> my_set = set(a)
>> print(my_set)
{'h', 'e', 'l', 'o'}

중간에 문자열 a를 set로 캐스팅한 my_set는 print결과 "l"의 중복을 허용하지 않고 "h", "e", "l", "o"만을 원소로 가짐을 알 수 있다.

 

Set는 집합연산을 위해 만들어진 것 답게 집합 연산과 같은 Union, isdisjoint, difference부터 단순 원소 추가 연산자인 add까지 지원한다. 

 

* 뭐 사실 난 set를 많이 안쓴다. 개인적인 생각으론 중요도도 다른 자료구조에 비해서 중요해 보이지 않고, 다른 자료구조로 처리될 수 있으면 set를 쓸 이유가 없다고 본다. 굳이 비슷한 자료구조가 필요하다면 만들어 쓰는 게 현명하다고 본다.

* set과 list는 상호 set()와 list()를 통해서 캐스팅이 가능하다 단 list > set으로 변환되었을 때 순서는 뒤죽박죽이 된다.


이렇게 이번시간에는 유일성 문제를 해결해주는 자료구조인 DICTIONARY와 SET에 대해서 알아보았다. 다음 시간은 기본자료구조의 마지막인 튜플에 대해서 알아보도록 하자