파이썬 리스트 총정리 : 인덱스찾기, append 추가함수, 정렬, 2차원구조

지난 시간에 파이썬의 변수 개념과 몇가지 기본적인 자료형, 수치형 (정수형 실수형) 문자형 논리형(불리언) 에 대해 알아보았다. 이번 시간에는 또 다른 데이터 타입인 리스트에 대해 공부해본다.

파이썬 리스트 정의와 선언

리스트는 여러가지 데이터를 한가지 변수에 저장할 수 있는 형태이다.

만약 한 반 학생 30명의 성적 데이터 30개가 있다면 변수를 어떻게 만들어서 저장해야 할까? 학생 이름별로 30개의 변수를 만들고 각각의 성적 수치를 입력하는 방법이 떠오를 것이다. 

하지만 파이썬에서는 30개의 성적 데이터를 하나의 변수에 몽땅 넣어 저장할 수 있는데 그것이 리스트이다.

파이썬 리스트

(발번역 주의)

리스트란?

  • 리스트는 아이템들의 정렬된 모음이다. (시퀀스 자료형)
  • 아이템은 파이썬의 어떠한 데이터 타입도 올 수 있다. (문자형, 수치형, 또 다른 리스트, 튜플, 사전)
  • C/JAVA/C++ 언어에서 말하는 어레이의 개념과 유사하다.
  • 리스트는 파이썬에서 가장 간단한 데이터 구조이다.
파이썬 리스트

리스트의 선언방법

colors = ['red' , 'blue' , 'green']

colors 라는 변수에 ‘red’ , ‘blue’ , ‘green’ 세 개의 문자형 데이터를 리스트 형태로 저장한 예시이다.

앞서 파이썬은 별도로 타입에 대한 정의를 해주지 않아도 변수의 선언과 동시에 타입이 지정되는 dynamic typing 언어라고 했었다. 위와 같이 대괄호 [square bracket] 을 이용하여 변수를 선언하면 데이터의 형태가 리스트가 된다.

리스트 원소 인덱싱과 슬라이싱

원소 인덱싱과 슬라이싱

이렇게 저장한 리스트는 각 원소별로 주소(offset) 값을 가진다. 리스트 내의 특정한 원소에 접근하는 것을 인덱싱이라고 하는데, 특정 원소(element)를 호출하기 위해서는 변수[offset] 형태로 주소값을 입력해주어야 한다.

## 리스트 변수 선언
colors = ['red' , 'blue' , 'green']

## 리스트 첫번째 원소 출력
colors[0]
red

## 리스트 두번째 원소 출력
colors[1]
blue

## 리스트 세번째 원소 출력
colors[2]
green

(중요) 리스트에서 첫번째 원소의 값은 0부터 시작한다. 리스트의 원소가 3개이면 각각 offset 값은 각각 0, 1, 2 가 된다. 아예 리스트의 값은 0번째 1번째 2번째 값을 가진다고 외워놓는게 편하다.

원소 인덱싱과 슬라이싱

반대로 뒤에서부터 호출하는 역인덱싱 방법도 있다. 뒤에서부터 호출할 때는 0이 아니라 -1부터임을 명심하자.

## 리스트 변수 선언
colors = ['red' , 'blue' , 'green']

## 리스트 뒤에서 첫번째 원소 출력
colors[-1]
green

## 리스트 뒤에서 두번째 원소 출력
colors[-2]
blue

## 리스트 뒤에서 세번째 원소 출력
colors[-3]
red
원소 인덱싱과 슬라이싱

element offset을 이용해 인덱싱하는 방법을 알았으니 이제 리스트의 특정 영역만 잘라내는 슬라이싱도 할 수 있다. 변수명[처음:끝] 과 같은 형태로 입력하면 처음~끝 구간에 있는 원소들만 잘라낼 수 있다. 이 때 또 주의할 점은 처음에 해당하는 위치의 원소부터 포함되지만 끝은 그 앞의 원소까지만 포함한다는 점이다. 예시를 보자.

원소 인덱싱과 슬라이싱

위와 같이 원소 5개짜리 리스트를 선언하고 변수명[처음:끝] 형태로 슬라이싱을 한다.

변수명[0:] ▶▶ 첫번째~끝까지

변수명[:4] ▶▶ 첫번째~4번째까지 (4 앞까지의 원소를 포함하는데 offset은 시작이 0이므로 0,1,2,3 4개를 포함한다.)

변수명[1:3] ▶▶ 두번째~세번째까지 (0빼고 1,2 offset의 원소 두개를 포함)

변수명[:] ▶▶ 첫번째~끝까지 (지정을 안하면 최대치로 인식해서 offset 0에서 끝까지를 모두 포함)

슬라이싱에서도 -를 이용하여 뒤에서부터 지정할 수 있다.

## 리스트 변수 선언
colors = ['yellow' , 'red' , 'blue' , 'green' , 'black']

## 리스트 뒤에서 3번째에서 뒤에서 1번째까지 출력
colors[-3:-1]
['blue' 'green']

## 리스트 전체를 offset 2개마다 하나씩 출력
colors[::2]
['yellow', 'blue', 'black']

## 리스트 뒤에서 세번째부터 앞에서 첫번째까지 역순으로 출력
colors[-3::-1]
['blue', 'red', 'yellow']

## 리스트 뒤에서 50번째에서 앞에서 50번째까지 출력
colors[-50:50]
['yellow', 'red', 'blue', 'green', 'black']

List[start:end:step] 형태로 입력할 수도 있는데 step 부분에 숫자2가 오면 2개마다 하나씩, 3이 오면 3개마다 하나씩 골라주라는 의미이다. -1이 오면 역순으로 나열, -2가 오면 역순으로 2개마다 하나씩 고른다.

또 아이템이 5개인데 구간을 -50~50으로 넓게 지정하면 그냥 최대치로 처음과 끝을 포함하는 구간으로 지정이 된다.

리스트 합치기와 값 수정하기

리스트로 지정된 변수끼리 합쳐서 출력하거나, 리스트의 각 원소를 수정하는 방법, 리스트에 원소들을 추가하는 방법 등을 살펴본다.

리스트 합치기와 수정

위와 같이 리스트를 편집할 수 있는 기능들 중에 몇 가지를 실습해볼 것이다.

리스트 합치기와 수정

먼저 리스트 두개를 +로 합치면 말그대로 앞에꺼 + 뒤에꺼가 쭉 순차적으로 나열된 새로운 형태의 리스트를 결과값으로 나타낸다. 이 때 기존 리스트의 내용이 바뀌는 것은 아니고 출력만 그렇게 해주는 것이다.

위에서 보듯이 변수 두 개를 합쳐서 출력했지만 각각의 변수들을 다시 출력해보면 바뀌지 않은것을 볼 수 있다.

리스트 합치기와 수정

더하기가 아닌 곱하기를 하면 그 리스트를 몇 번 반복해서 붙여넣으라는 의미로, 자기 자신을 셀프 더하기 하는 것과도 같다.

리스트 합치기와 수정

len(리스트명) 은 리스트의 길이, 원소의 개수를 알려준다.

리스트 합치기와 수정

append는 리스트의 마지막에 원소를 추가하는 명령어이다. 여기서는 리스트형 변수의 데이터 자체가 변하게 된다. 

리스트 합치기와 수정

insert는 특정 index (offset주소) 에 값을 추가하는 명령어이다.

리스트 합치기와 수정

remove는 특정 값을 제거한다.

리스트 합치기와 수정

값이 아닌 offset 주소로 제거하고 싶다면 del 을 이용하면 된다.

리스트 합치기와 수정

sort를 이용하면 오름차순 정렬을 할 수 있고

리스트 합치기와 수정

reverse를 이용하면 내림차순 정렬을 할 수 있다. 여기까지 본 몇 가지 명령어들을 실습해보자.

## 리스트 길이 확인
colors = ['yellow' , 'red' , 'blue' ]
len(colors)
3


## 리스트 마지막에 값 추가
colors = ['yellow' , 'red' , 'blue' ]
colors.append('orange')
colors
['yellow', 'red', 'blue', 'orange']


## 리스트 마지막에 다른 리스트 형태를 추가
colors = ['yellow' , 'red' , 'blue' ]
colors.extend(['white','black'])
colors
['yellow', 'red', 'blue', 'white', 'black']


## 리스트 특정 주소에 값 추가
colors = ['yellow' , 'red' , 'blue' ]
colors.insert(1,'black')
colors
['yellow', 'black', 'red', 'blue']


## 리스트 값 삭제
colors = ['yellow' , 'red' , 'blue' ]
colors.remove('blue')
colors
['yellow', 'red']


## 리스트 특정 주소의 값 삭제
colors = ['yellow' , 'red' , 'blue' ]
del colors[0]
colors
['red', 'blue']


## 리스트 오름차순 내림차순 정렬
colors = ['yellow' , 'red' , 'blue' ]
colors.sort()
print(colors)
colors.reverse()
print(colors)
['blue', 'red', 'yellow']
['yellow', 'red', 'blue']

리스트의 메모리 저장원리

파이썬 언어만 공부하는 것이 아니라 컴퓨터의 데이터 저장원리에 대해서도 이해를 하고 있어야 나중에 도움이 된다. 아래 두가지 예시의 차이를 통해 메모리에 어떻게 값이 저장되는지 개념을 얻어본다.

a, b 두개의 리스트를 선언하고 초기값 확인, b를 a에 복사한 후 값을 확인, a를 오름차순 정렬시킨 후 값을 확인하는 형태의 코드이다.

리스트 저장원리

첫번째 예시이다. a와 b 두개의 리스트형 변수를 선언하고 초기값을 확인한다. 그리고 b=a를 해주었는데 이는 b가 앞으로 a를 가리킨다는 의미이다. 파이썬에서 변수란 일종의 메모리 주소라고 하였다. (포스팅 상단 이전글 링크 참조)

따라서 b=a라는건 b에 a의 값을 넣으라는 의미가 아니라, 앞으로 b의 메모리 주소는 a의 메모리 주소를 가리켜라 라는 뜻으로 보아야 한다. 즉 b가 가지고 있던 도로명주소를 a랑 같은 도로명 주소를 가지도록 ‘동기화’ 시켜라 라는 것이다.

그 다음에 a를 오름차순 정렬로 바꾼후 살펴보면 b도 같이 바뀐것을 알 수 있다. b가 a의 메모리 주소를 같이 가리키고 있기 때문에 a가 어떻게 바뀌면 b도 따라서 바뀌는 것이다.

리스트 저장원리

두번째 예시는 b=a가 아니라 b=a[:] 형태로 복사하였다. 이것은 a가 가지고 있는 리스트 속의 인덱스 [:] 즉 첫번째에서 끝까지 값을 말한다. a 변수 자체가 아니라 a가 가지고 있는 값을 b에 넣었다는 의미이다.

그래서 a의 값을 b에 넣은 후에는 print를 해보면 a와 b가 같지만, a를 오름차순 정렬로 값을 바꾼 후 다시 확인해보면 a만 바뀌고 b는 바뀌지 않았음을 알 수 있다.

이 경우에는 a와 b가 선언과 동시에 각각의 메모리 주소를 할당받았고 그 다음에 b의 메모리 주소에 a 메모리 주소에 있던 ‘값들’만 가져와서 똑같이 넣었다. 그리고 a 메모리 주소에 있는 값들만 오름차순 정렬로 바꾸어 준 것이다. 따라서 b의 메모리 주소에 있는 값들은 같이 바뀌지 않았다.

이차원 리스트로 행렬 만들기

마지막으로 리스트의 중첩 구조를 통한 매트릭스 형태의 데이터 구성에 대해 알아본다.

이차원 리스트 행렬

리스트가 가질 수 있는 값은 파이썬의 모든 데이터 형태라고 하였는데, 다른 리스트를 리스트 속에 하나의 값처럼 가질수도 있다. 이를 통해 이차원 이중 리스트를 만들고 행렬처럼 데이터를 구성할 수 있다.

이차원 리스트 행렬

이렇게 리스트형 변수 세개를 선언하고 또다른 변수에 그 리스트들을 원소로 가지도록 설정해주면, 리스트 안에 리스트가 있는 형태로 만들어 진다. 이차원으로 만들었지만 이런 식으로 삼차원 사차원 얼마든지 할 수 있다.

이차원 리스트 행렬

이중 구조로 되어있을 때 인덱싱은 어떻게 해줄까. 이렇게 대괄호를 두 번 사용해서 첫번째 인덱싱, 두번째 인덱싱을 순서대로 해주면 된다. 행과 열을 지정해서 매트릭스 행렬 구조에서 찾는 것과도 같은 원리이다. 

어떠한 표가 있으면 행으로 한 줄씩 하나의 리스트로 만들고 그 각각을 묶어서 이중구조로 해주면, 이렇게 행 (row) 열 (col) 지정을 통해 리스트 내에서 원하는 값을 인덱싱할 수 있다.

위의 예시를 매트릭스 행렬로 나타내면 아래와 같다.

 col1col2col3
row1a1a2a3
row2b1b2b3
row3c1c2c3

여기서 list[행][열] 식으로 지정해서 원하는 위치의 데이터를 불러올 수 있다.