우리는 지금까지 상수 / 실수 / 문자열 변수의 사용과 그 연산을 자유자재로 할 수 있게 되었다.(할 수 있음 아무튼 그럴 거임). 커지는 프로그램은 필연적으로 많은 변수를 생성하게 되어있다. 예를 들어 교실 관리를 하게 된 우리가 프로그램을 만들고 있는데, 학생의 이름을 변수에 배정한다고 가정하자 우리는 늘 하던 대로 30명의 학생을 관리하기 위해
>> student1="김철수"
>> student2="배철수"
>> student3="윤철수"
>> student4="남궁철수"
...
>>> student30="독고철수"
이러한 변수를 만들었다. 그런데 뭔가 이상하다. 더 좋은 방법이 있을 거 같은데... 변수 이름이 너무 많이 생성되는 기분이 든다. 어쩌면 한 변수 안에 많은 것을 담을 수 있지 않을까??
이러한 문제는 LIST를 사용함으로써 완벽히 해결된다..
LIST의 정의와 사용
LIST는 변수를 일렬로 담아둔 선형구조(일자 구조)의 자료구조이다.
LIST는 지정할 변수명 = list()와 같은 식으로 list를 생성할 수 있고, Python의 문법에 따라 대괄호[ ]로 지정을 하게 되는데, 지정할 변수명 = [(변수 1), (변수 2), (변수 3)... ]의 식으로 초기화까지 진행할 수 있다.
>> student = ["김철수","배철수","윤철수"]
이제 우리는 student를 30번 치는 멍청한 행동을 하지 않아도 된다! 그런데... 어떻게 student변수의 "김철수"를 사용할 수 있을까? 다음과 같이 print를 하면 LIST전체가 출력된다.
>> print(student)
["김철수","배철수","윤철수"]
본격적으로 LIST를 사용하기 위해서 인덱스의 개념을 알아야 한다.
인덱스(index)
인덱스란 순서이다. 즉 student의 몇 번째 순서(인덱스)에 있는 변수를 사용할 것이다 처럼 특정한 자료구조의 위치를 집어주는 역할을 해준다. 사용법은 변수명[인덱스]으로 사용한다.
>> print(student[0])
"김철수"
>> print(student[1])
"배철수"
>> print(student[2])
"윤철수"
* 인덱스는 항상 0으로 시작한다. 따라서 "김철수"는 student의 0번째 원소인 것이다. >> 이렇게 1번째부터 만들지 않은 이유는 메모리 구조로 설명할 수 있다. 변수를 만든다는 행위는 메모리에 크기를 할당한다는 행위이며, 배열을 만드는 것은 연속적인 크기를 할당하는 의미인데, 변수의 이름 그 자체가 0번째 자리하는 원소를 의미하기 때문에. 관례적으로 0번째를 첫 번째 원소로 사용한다. 이는 C언어나 메모리를 공부하면 더 깊이 알 수 있다.
LIST는 여러 가지 메소드(함수)를 제공하는데 다음과 같은 기능이 많이 사용된다.
[LIST형 변수명].append(원소) : 리스트에 원소를 추가한다.
[LIST형 변수명].insert(위치, 원소) : 리스트에 특정한 위치에 원소를 삽입한다.
[LIST형 변수명].clear() : 리스트의 원소를 전부 제거한다.
[LIST형 변수명].sort() : 리스트의 원소를 정렬한다.
[LIST형 변수명].count(원소) : 리스트의 원소 개수를 셈한다.
[LIST형 변수명].index(원소) : 특정한 원소의 인덱스를 출력한다.
다음은 자주 사용하는 메소드의 예시이다.
>> my_list = [3,2,1,5,4]
>> my_list.append(6)
## my_list는 [3,2,1,5,4,6]
>> my_list.insert(2,5)
## my_list는 [3,2,5,1,5,4,6] 2번째인덱스에 5를 집어넣었다.(인덱스는 항상 0부터!)
>> my_list.sort()
## my_list는 [1,2,3,4,5,5,6]
>> my_list.count(5)
2
>> my_list.index(4)
3
>> my_list.clear
## my_list는 []
* 개발도구에 따라 다르지만, my_list와 점(.)까지 입력을 하고 탭[Tab]을 하거나 가만히 있으면, 사용할 수 있는 기능들의 목록을 보여준다. 이것을 메서드(함수)라고 부르는데, 지금은 ① 이것은 메서드라고 부른다는 것 ② 자료구조에 따라 사용할 수 있는 메서드가 다르다는 것 ③ 메서드는 사용할 때 0개 이상의 괄호 안에 들어갈 매개변수가 필요하다는 것
이렇게만 알아두도록 하자
Python의 LIST에는 서로 다른 자료형을 담을 수 있다. 즉 a=[1,2, "bbb", "ccc"]도 가능하고, 담을 수 없어 보이는 람다 함수(나중에 배울 예정이다.)이나 다른 자료구조 또한 담을 수 있다. 이해의 확인을 위해서 다음의 코드를 보도록 하자
>> my_list = [1,2,3]
>> new_my_list = [4,5,my_list]
>> print(new_my_list"네모")
2
여기서 "네모"에 들어갈 값은 무엇일까? 일단 2는 my_list [1]이다. new_my_list에서 my_list는 2의 인덱스에 존재하니
new_my_list [2]가 곧 my_list가 되는 것이고 우리는 my_list [1]를 출력하고 싶은 것이니 정답은 [2][1]이 된다.
>> my_list = [1,2,3]
>> new_my_list = [4,5,my_list]
>> print(new_my_list[2][1])
2
이것과 같이 배열이 2번 중첩된 것을 2차원 배열이라고 한다. 눈치 빠른 사람들은 알겠지만, 3번 중첩되면 3차원 배열, n번 중첩되면 n차원 배열이라고 한다.(물론 4차원 이상의 배열을 쓰는 경우는 드물다.)
* 차원이라고 부르는 이유는 이것이 곧 축과 상응되기 때문이다. 1차원 배열의 원소들이 일자로 쭉 이어진 상자라면, 2차원 배열의 원소들은 사각형에 존재하는 상자들이고, 3차원 배열은 직육면체에 존재하는 상자들이다.(인덱스로 접근하는 방식을 추상화하면 그렇다는 것이다. 컴퓨터에 저장되는 메모리가 직육면체로 있지는 않다.)
캐스팅 - LIST <> 문자열
LIST가 제공하는 강력한 메서드(함수) 들을 보았으면 이제 LIST 없이는 살 수 없는 몸이 돼버렸을 가능성이 있다. 가령 문자열로 만든 a="Hello World"의 a[3]은 "l"이라는걸 Python은 알려주겠지만, a[3] = "n"로 만들어 "Henlo World"를 만드는 일은 문자열 자료형에서는 불가한 일이니 말이다. 그래서 우리는 LIST로의 캐스팅을 자유자재로 할 줄 알아야 한다. 다음은 문자열과 리스트의 상호 변환 방법이다.
>> a="hello world"
>> a=list(a)
## a를 list로 캐스팅
>> print(a)
['h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd']
>> a = ''.join(a)
## ?? 단순한 캐스팅이 아니다. a=str(a)를 하게되면 "['h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd']"
## 로 통째로 문자열이 되버린다.
>> print(a)
"hello world"
이번 시간에는 Python의 강력한 자료구조 중 하나인 LIST에 대해서 알아보았다. 2차 3차의 자료구조가 되면서 어려워지는 것이 이 LIST이지만, 기초가 단단하면 어떠한 LIST를 만나더라도 자유자재로 다룰 수 있을 것이라고 자신할 수 있다. 아직 어려운 부분은 아니지만 이해가 안 된다면 몇 번이고 다시 읽어보자. 다음 시간에는 다른 자료구조인 DICTIONARY와 SET에 관하여 알아보자
'Python > 파이선과 친해지기' 카테고리의 다른 글
[Python] - Python과 친해지기-TUPLE (0) | 2021.04.05 |
---|---|
[Python] - Python과 친해지기-DICTIONARY와 SET (0) | 2021.04.05 |
[Python] - Python과 친해지기-자료형과 형변환 (0) | 2021.04.04 |
[Python] - Python과 친해지기-변수와 연산 (0) | 2021.04.04 |
[Python] - Python과 친해지기-Hello World와 정수 (0) | 2021.04.04 |