1. 리스트(List)

이번 편에서는 리스트(List)에 대해 알아 보도록 하겠습니다. 우리가 배울 파이썬에서의 리스트(List)란, 순서가 있는 값들의 나열이라고 할 수 있습니다. 리스트를 구성하는 값을 요소 혹은 원소라고 부르며 어떠한 타입의 값이든 리스트의 요소로 올 수 있습니다. 이는 한가지의 타입으로만 이루어진 리스트뿐만 아니라, 여러가지 타입의 데이터로 이루어진 리스트를 구성할 수 있다는 말입니다. 이러한 리스트를 만드는 방법은 간단합니다. 요소들을 대괄호로 둘러싸고, 요소와 요소의 사이에는 콤마(,)로 구분을 해주면 됩니다.

>>> lst = [1, 2, 5, 'a', 'b']
>>> lst
[1, 2, 5, 'a', 'b']
>>> type(lst)
<class 'list'>

리스트를 보니 왠지 모르게 편할것 같은 생각이 들지 않나요? 위의 예 말고도 여러가지 리스트를 만들어 보도록 해봅시다. 리스트의 요소로 아무것이나 한번 넣어보도록 하겠습니다.

>>> lst = ['a', 3.14, 55555, 'abcdef', ['a', 'b', 'c']]
>>> lst
['a', 3.14, 55555, 'abcdef', ['a', 'b', 'c']]
>>> lst = [3.14132323, 3535242, 'abc', "def", 'color']
>>> lst
[3.14132323, 3535242, 'abc', 'def', 'color']

위의 코드와 결과를 보시면, 리스트 내에 실수와 정수, 문자열이 들어가고 심지어 리스트 내에 리스트가 들어가기도 한다는 것을 보실 수 있습니다. 이러한 리스트에도 우리가 '문자열'편에서 배운 인덱싱과 슬라이싱이란 개념이 존재합니다.

>>> lst = [1, 2, 'a', 'b', 'red', 'beaf', ['a', 'b', 'c']]
>>> lst[3]
'b'
>>> lst[-2]
'beaf'
>>> lst[1:3]
[2, 'a']
>>> lst[2:5]
['a', 'b', 'red']
>>> lst[6][2]
'c'

문자열과 똑같이, 리스트에도 0부터 시작하는 인덱스(index, 첨자)라는 녀석이 존재하며 시작 위치와 끝 위치를 가지고 잘라낸 요소 리스트를 가져올 수 있습니다. 아직 위 코드에서의 인덱싱과 슬라이싱이 잘 이해가 되지 않으시는 분들을 위해, 추가 설명을 보태도록 하겠습니다. 예를 들어서, 'lst[-2]'에서는 인덱스에 음수가 쓰였으므로 리스트 lst의 요소를 뒤에서부터 읽게 됩니다. 이것은 뒤에서 두번째에 있는 요소를 읽게 되는 것이라고 할 수 있습니다. 그리고 슬라이싱을 예로 들어서 'lst[2:5]'와 같은 문법은, 2가 시작 위치이고 5가 끝 위치를 의미하나 끝 위치는 범위에서 제외하므로 실제로는 위치 2, 3, 4에 있는 요소를 읽어오는 것입니다.


다시 돌아와서, 1행을 보시면 만들어진 리스트에서, 또 다른 리스트가 중첩되었음을 보실 수 있는데 이어서 10행에 쓰인 코드를 보시면 인덱싱이 조금 이상하죠?

'lst[6][2]'는 위치 6에 해당하는 요소의 위치 2에 있는 요소를 가져옵니다. 만약 lst[6][2]에도 리스트가 있다면, 'lst[6][2][위치]' 이런식으로 사용할 수 있을 것입니다. 그러나, 이렇게 리스트가 여러번 중첩되는 복잡한 형식은 잘 사용되지 않으나 알아두시는게 좋습니다.


그리고 리스트는 문자열과는 다르게 인덱싱을 통하여 리스트의 요소를 변경할 수 있습니다.

>>> lst = [1, 2, 'a', 'b', 'red', 'beaf']
>>> lst[2] = 3
>>> lst[4] = 'blue'
>>> lst
[1, 2, 3, 'b', 'blue', 'beaf']

또한, 문자열과 마찬가지로 리스트도 지원하는 연산자가 여럿 존재합니다. 그 중에서도 리스트를 연결하는 + 연산자와, 리스트를 반복하는 * 연산자에 대한 예제를 한번 보도록 하겠습니다.

>>> lst1 = ['A', 'B', 'C']
>>> lst2 = ['D', 'E', 'F']
>>> lst1 + lst2
['A', 'B', 'C', 'D', 'E', 'F']
>>> lst1 * 3
['A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C']

위의 코드와 결과를 보시면, lst1과 lst2를 서로 연결하여 ['A', 'B', 'C', 'D', 'E', 'F']가 되며 리스트 lst1을 3번 반복하여 ['A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C']가 됨을 알 수 있습니다. 그리고, 이러한 연산자 뿐만이 아니라 리스트와 관련된 여러가지 함수가 존재합니다. 이번에는 리스트에 관련된 함수를 중점적으로 설명을 하도록 하겠습니다.


2. 리스트 관련 함수

리스트와 관련된 함수 중 추가, 삽입, 확장, 위치 등에 관한 9가지의 함수에 대해서 알아보도록 하겠습니다. 먼저 추가에 관련된 함수부터 시작하여 차례대로 알아가보도록 하겠습니다.


  리스트 - 추가(append) 함수

리스트에 요소를 추가하는 함수인 append 함수에 대해서 알아보도록 하겠습니다. 기존의 리스트에 있는 요소에 다른 값을 추가하려면 아래와 같이 append 함수를 사용하시면 됩니다.

>>> fruit = ['apple', 'banana', 'pineapple']
>>> fruit.append('grape')
>>> fruit
['apple', 'banana', 'pineapple', 'grape']

위의 코드와 결과를 보시면, 리스트인 fruit에 grape라는 값을 요소로 추가하고 있음을 확인하실 수 있습니다. append 함수를 통해서 'grape'라는 값이 제대로 리스트에 추가되었음을 보실 수 있습니다. 리스트에 새로 값이 추가되는 위치는 가장 뒤에서 요소가 추가된다는 것도 알 수 있습니다. 리스트의 요소로 어떠한 타입의 값이든 올 수 있는것처럼, append 함수로 추가되는 값의 타입도 아무런 타입이 올 수 있음을 의미합니다.

>>> lst = ['A', 'B', 1, 2, 3.14, 10.16]
>>> lst.append([1, 2, 3])
>>> lst
['A', 'B', 1, 2, 3.14, 10.16, [1, 2, 3]]

추가되는 값의 형태가 리스트일 수도 있으며, 정수, 튜플 등 여러가지 타입이 올 수 있습니다. 잘 와닿지 않으신다면, 여러가지 타입의 값을 함수를 통해서 추가를 해보도록 하시는 것도 좋을것 같습니다.


  리스트 - 삽입(insert) 함수

리스트에 요소를 삽입하는 함수인 insert 함수에 대해서 알아보도록 하겠습니다. 뒤에서부터 추가되는 append 함수와는 달리, 이 insert 함수는 지정한 위치에 추가하려는 값을 넣을 수 있습니다. 우선은 insert 함수를 어떻게 사용하는지에 대해 보도록 하겠습니다.

>>> lst = [1, 2, 4, 5, 6]
>>> lst.insert(2, 3)
>>> lst
[1, 2, 3, 4, 5, 6]

위 코드에서 두번째 행을 보시면, 첫번째 공간에는 2라는 숫자와 두번째 공간에는 3이라는 숫자가 있죠? 이 둘은 인수(argument)라고 하며, 우선은 인수가 '함수에게 필요한 정보'라고 생각합시다. 첫번째 인수는 요소가 추가될 위치를 말하는 것이며, 두번째 인수에는 리스트에 삽입될 값이 들어옵니다. 위를 보시면, 위치 2에 3이라는 값이 추가되었다고 보시면 됩니다. 또 비슷한 경우를 볼까요?

>>> nums = ['one', 'two', 'three', 'five', 'six']
>>> nums.insert(3, 'four')
>>> nums
['one', 'two', 'three', 'four', 'five', 'six']

위 예제에서는 두번째 행을 보시면, 위치 3에 'four'이란 값이 추가되었다고 보시면 됩니다. 말 그대로 삽입(insert) 함수이며, 추가(append) 함수와는 위치에서 차이가 난다고 할 수 있습니다. 추가 함수는 뒤에서 부터 추가되는 반면에, 삽입 함수는 우리가 지정한 위치에 값이 들어가는 것이라고 할 수 있습니다. 이해되시죠?


  리스트 - 확장(extend) 함수

리스트를 확장하는 함수인 extend 함수에 대해서 알아보도록 하겠습니다. 이 extend 함수는 한가지씩 값이 추가되는 append 함수와 달리, 여러개의 값을 추가할 수 있습니다. 한가지 주의하실 점이 있다면, 함수로 전달되는 인수에는 리스트만 올 수 있다는 사실을 기억해두시기 바랍니다.

>>> nums = [1, 2, 3, 4, 5, 6]
>>> nums.extend([7, 8, 9])
>>> nums
[1, 2, 3, 4, 5, 6, 7, 8, 9]

extend 함수에 전달되는 인수를 보니 리스트인 [7, 8, 9]가 전달되었음을 알 수 있습니다. 확장을 거친 후에는, 전달된 리스트와 리스트 nums가 연결된 것을 확인하실 수 있습니다. 추가 함수인 append 함수와 마찬가지로, extend 함수도 리스트의 뒤에서 추가됩니다.


  리스트 - 위치 확인(index) 함수

리스트에 있는 특정 요소의 위치를 확인하는 함수인 index 함수에 대해서 알아보도록 하겠습니다. 이 index 함수의 첫번째 인수로는 찾으려는 요소의 값이 들어가며, 두번째 인수에는 탐색이 시작하는 위치, 세번째 인수에는 탐색이 종결되는 위치가 들어갑니다. 두번째 인수와 세번째 인수는 생략할 수 있습니다.

>>> lst = ['red', 'blue', 'green', 'yellow', 'white', 'black', 'blue']
>>> lst.index('blue')
1
>>> lst.index('blue', 2)
6
>>> lst.index('yellow', 2, 4)
3

위에 있는 코드와 결과에서, 2행을 보시면 'blue'가 처음으로 등장하는 요소의 위치를 출력한다는 것을 아실 수 있습니다. 그리고 4행에서는 시작점이 위치 2인데, 위치 2 이후에 등장하는 'blue'는 위치 6에 존재하므로 6이라는 결과가 출력되는 것입니다. 그리고 마지막으로, 6행에서는 시작점이 위치 2이며, 종결점이 위치 4임을 보실 수가 있습니다. 이는 위치 2와 위치 4를 포함한, 그 사이에 있는 'yellow'의 위치를 출력하는 것입니다. 위치는 1부터가 아니라, 0부터 시작한다는 사실을 잊지 말고 계세요.


  리스트 - 요소 수(count) 함수

리스트에 존재하는 특정 요소의 수를 확인하는 함수인 count 함수에 대해서 알아보도록 하겠습니다. count 함수를 통해서 요소 개수를 확인하려면, count 함수로 해당하는 요소를 건네주면 됩니다. 한번 확인해보도록 합시다.

>>> lst = [1, 1, 2, 3, 4, 5, 6, 6, 6, 7]
>>> lst.count(1)
2
>>> lst.count(6)
3

위 예제의 2행을 보시면, 요소 1이 리스트 lst 내에 있는 개수를 가져오며 4행도 마찬가지로 요소 6이 리스트 내에 있는 개수를 가져옵니다. 직접 lst의 요소를 확인해보시면 정말로 1이 두개, 6이 세개라는 사실을 알 수 있습니다. 참으로 간단하죠?


  리스트 - 요소를 꺼내는(pop) 함수

리스트의 요소를 꺼내는 함수인 pop 함수에 대해서 알아보도록 하겠습니다. pop 함수는 인수를 아에 생략하고 사용할 수 있으며, 특정한 요소를 리스트에서 꺼내려면 함수의 첫번째 인수로 꺼내려는 요소의 위치를 적어주시면 됩니다. 한번 pop 함수를 사용해보도록 합시다.

>>> lst = ['a', 'b', 'c', 'd', 'e']
>>> lst.pop()
'e'
>>> lst
['a', 'b', 'c', 'd']
>>> lst.pop(1)
'b'
>>> lst
['a', 'c', 'd']

위 예제에서 2행을 보시면 인수를 따로 적지않고 그냥 함수를 사용하였는데, 이 경우에는 리스트의 가장 뒤에 있는 요소를 꺼내가게 됩니다. 그리고 6행과 같이 위치를 넘겨주면, 그 위치에 있는 요소가 리스트에서 제외됩니다.


  리스트 - 제거(remove) 함수

리스트의 요소를 제거하는 함수인 remove 함수에 대해서 알아보도록 하겠습니다. 이 remove 함수는 pop 함수와는 달리, 리스트 내에서 해당하는 값만을 제거합니다. 만약, 제거하려는 값이 리스트에 여러개가 존재하면 가장 앞에있는 요소부터 제거가 됩니다. 한번 remove 함수를 사용해보도록 합시다.

>>> a = [1, 2, 1, 3, 4, 1]
>>> a.remove(1)
>>> a
[2, 1, 3, 4, 1]

위의 예제에서 2행을 보시면 리스트 a 내에 1이라는 값을 제거하려고 하는데, 리스트 a에는 1이란 값이 3개나 있습니다. 이 경우에는 위에서 말한대로 가장 앞에있는 요소부터 제거가 된다고 했습니다. 그렇기 때문에, 가장 앞에 있는 1이 우선 제거가 되는 것입니다. 만약 'a.remove(2)' 였다면, 리스트 a에 있는 2라는 값을 제거한다고 할 수 있습니다.


  리스트 - 정렬(sort) 함수

리스트의 요소들을 정렬하는 함수인 sort 함수에 대해서 알아보도록 하겠습니다. 우선은 이 함수로 전달되는 인수를 통해서, 정렬 방식을 변경할 수도 있으며 반전 여부도 지정할 수 있습니다. 우선은 sort 함수로 인수를 넘겨주지 않은 간단한 예제를 살펴보도록 하겠습니다.

>>> a = [3, 5, 1, 2, 7]
>>> a.sort()
>>> a
[1, 2, 3, 5, 7]

위 예제를 보시면, 2행에서 sort 함수가 사용되고 나서 3행에서 리스트 a가 정렬되었다는 것을 확인하실 수 있습니다. 물론 이렇게 순서대로 정렬할 수도 있겠지만, 반대로 역순으로 정렬할 수도 있습니다.

>>> a = [3, 5, 1, 2, 7]
>>> a.sort(reverse=True)
>>> a
[7, 5, 3, 2, 1]

위 예제의 결과를 보시니 리스트가 역순으로 정렬됨을 확인하실 수 있습니다. 저렇게 reverse를 True로 만들어 주지 않을 경우에는, reverse의 기본값이 False이기 때문에 순서대로 정렬된 데이터를 보실 수 있습니다. 편리하죠?


  리스트 - 반전(reverse) 함수

리스트를 역순으로 뒤집는 함수인 reverse 함수에 대해서 알아보도록 하겠습니다. 이 함수는 단순히 리스트의 요소들을 모두 역순으로 뒤집는 역할만 하며, 정렬과는 상관이 없습니다. 한번 같이 reverse 함수를 살펴보도록 합시다.

>>> a = [1, 3, 5, 7, 9]
>>> a.reverse()
>>> a
[9, 7, 5, 3, 1]

위 예제를 보시면, 2행에서 reverse 함수가 사용되고 나서 4행에서 리스트 a가 반전되었음을 알 수 있습니다. 말 그대로, 리스트 a의 요소들을 뒤집었다고 생각하시면 됩니다.