본문 바로가기
Python

[Python] 리스트(list) 자료형 사용법 및 예제

by A6K 2022. 10. 30.

리스트는 일련의 데이터를 묶어서 같이 처리할 수 있게 해주는 자료형 중 하나다. 관련있는 데이터들을 하나의 리스트에 담아서 함께 처리하는 코드는 파이썬에서 굉장히 흔하게 사용된다.

이번 포스트에서는 리스트에 대한 설명과 리스트에 담긴 데이터를 다루는 방법에 대해서 설명하고 예제를 통해 활용해보겠다.

리스트(list) 생성

파이썬에서 리스트 객체는 두 가지 방법으로 생성할 수 있다.

fruits = ['apple', 'banana', 'pear', 'strawberry', 'cherry']
empty_list = []

우선 첫 번째로 대괄호로 하나의 리스트에 담을 데이터를 모아서 선언하는 방법이 있다. 위 코드를 보면 apple, banana, pear, strawberry, cherry를 엘리먼트로 갖는 fruits라는 리스트를 선언한다. 만약 대괄호 안에 엘리먼트를 명시하지 않으면 빈 리스트 객체가 생성된다.

C나 Java와 다르게 파이썬의 리스트는 모든 엘리먼트가 동일한 타입일 필요는 없다. 즉, 다음과 같은 형태로 리스트 객체를 생성해도 상관없다.

my_list = ['apple', 2, 3, 'blog', 1.7]

리스트를 만들기 위해서는 list() 함수를 호출해도 된다.

empty_list = list()
my_list = list(range(1, 10))
my_list2 = list(range(1, 10, 3))

print(my_list)
print(my_list2)

# [1, 2, 3, 4, 5, 6, 7, 8, 9]
# [1, 4, 7]

list() 만 호출하면 빈 리스트 객체가 만들어지고, 초기화하고 싶은 범위의 숫자를 range()를 통해 지정하면 그 범위의 숫자를 담은 리스트 객체가 만들어진다. 만약 1씩 증가하는 것이 아니라 3씩 증가하는 숫자를 포함하고 싶다면 range() 함수에 추가로 3을 입력해주면 된다. 

만약 어떤 범위의 숫자 중 특정 조건을 만족하는 엘리먼트만 포함하는 리스트를 만들고 싶은 경우라면 리스트 컴프리헨션(list comprehension)을 이용하면 된다. 예를 들어 1부터 10 사이의 숫자 중 짝수만 포함하는 리스트를 만들고 싶다면

even = [x for x in range(1, 10) if x % 2 == 0]

print(even)

# [0, 2, 4, 6, 8]

for 문이 1부터 9까지 돌면서 x를 뽑아오고, x를 2로 나눈 나머지가 0이면 즉 짝수면 포함하겠다는 의미다.

리스트 요소 접근

파이썬의 리스트에 담겨 있는 각 엘리먼트들은 순서가 정해져 있다. 따라서 리스트 변수 뒤에 대괄호를 열고 몇 번째 엘리먼트에 접근하고자하는지 숫자를 입력하면된다. 이 숫자를 리스트의 인덱스라고 하며, 0부터 시작한다.

예를 들어 fruits 리스트에 있는 두 번째 엘리먼트를 읽어오고 싶다면 fruits[1]로 접근하면 된다. 유의할 점은 엘리먼트의 접근은 0부터 시작한다는 점이다. 다른 언어에 있는 배열과 비슷하다고 할 수 있다.

fruits = ['apple', 'banana', 'pear', 'strawberry', 'cherry']
print(fruits[0])
print(fruits[1])
print(fruits[2])
print(fruits[3])
print(fruits[4])

# apple
# banana
# pear
# strawberry
# cherry

만약 리스트에 있는 엘리먼트 갯수에 맞지 않는 숫자를 입력하면, 즉 리스트에 없는 인덱스 번호를 입력하면 IndexError가 발생한다.

fruits = ['apple', 'banana', 'pear', 'strawberry', 'cherry']
print(fruits[0])
print(fruits[1])
print(fruits[2])
print(fruits[3])
print(fruits[4])
print(fruits[5])

# apple
# banana
# pear
# strawberry
# cherry
# Traceback (most recent call last):
#   File "./test.py", line 7, in <module>
#     print(fruits[5])
# IndexError: list index out of range

리스트의 인덱스는 음수로 지정할 수도 있다. 음수로 지정할 경우 리스트의 뒤에서 몇 번째인지를 의미한다.

fruits = ['apple', 'banana', 'pear', 'strawberry', 'cherry']
print(fruits[-1])
print(fruits[-2])
print(fruits[-3])
print(fruits[-4])

# cherry
# strawberry
# pear
# banana

인덱스는 0부터 시작하기 때문에 리스트의 인덱스 1은 두 번째 엘리먼트라고 했다. 하지만 -0은 없기 때문에 뒤에서부터 셀때에는 -1이 뒤에서 첫 번째 엘리먼트를 의미하는 것임을 유의하자. 

리스트의 각 원소 값을 여러개의 변수에 하나의 문장으로 나눠서 담을 수 있다. 

l = [1, 2, 3]
v1, v2, v3 = l

print(v1)
print(v2)
print(v3)

# 1
# 2
# 3

다만 이런 복수 할당 방법에서는 리스트에 담겨있는 엘리먼트 개수와 복수 할당에 사용한 변수의 숫자가 맞아야 한다. 그렇지 않으면 ValueError가 발생한다.

l = [1, 2, 3]
v1, v2 = l

print(v1)
print(v2)

# Traceback (most recent call last):
#   File "./test.py", line 5, in <module>
#    v1, v2 = l
# ValueError: too many values to unpack (expected 2)

중첩된 리스트

리스트의 엘리먼트로 다른 리스트를 포함할 수 있다. 예를 들어

fruits = ['apple', ['banana', 'cherry'], ['pear', 'strawberry']]

print(fruits[0])
print(fruits[1])
print(fruits[1][0])
print(fruits[1][1])
print(fruits[2])
print(fruits[2][0])
print(fruits[2][1])

# apple
# ['banana', 'cherry']
# banana
# cherry
# ['pear', 'strawberry']
# pear
# strawberry

fruits 리스트의 엘리먼트는 'apple'과 또 다른 리스트인 ['banana', 'cherry'], ['pear', 'strawberry']를 가질 수 있다. 이 때, 중첩된 리스트의 엘리먼트를 따라가는 것은 간단하다. fruits[1]은 두 번째 엘리먼트인 ['banana', 'cherry'] 리스트를 의미한다. 여기서 banana를 뽑아오기 위해서는 fruits[1][0]으로 접근하면 된다.

리스트 수정

리스트의 인덱스를 통해 특정 엘리먼트의 값에 접근하는 방법을 배웠다. 이 인덱스를 가지고 특정 엘리먼트의 값을 수정할 수도 있다.

fruits = ['apple', 'banana', 'pear', 'strawberry', 'cherry']
fruits[1] = 'mango'

print(fruits)

# ['apple', 'mango', 'pear', 'strawberry', 'cherry']

fruits 리스트의 두 번째 엘리먼트 값을 'banana'에서 'mango'로 바꾸는 예제다. 두 번째 엘리먼트에 접근하기 위해서 [1]이라는 인덱스를 사용했고, 거기에 'mango'를 할당하면 리스트의 두 번째 엘리먼트가 변경된다.

리스트 슬라이스

리스트의 슬라이스 연산은 리스트를 특정 방법으로 자르는(Slice) 동작이다. 예를 들어서 리스트의 처음 3개의 엘리먼트만 잘라서 쓰고 싶은 경우나 중간에 있는 특정 부분을 떼어내고 싶은 경우에 사용한다.

파이썬에서 리스트의 슬라이스 연산은 인덱스 번호와 콜론(:) 문자를 이용해서 사용할 수 있다. 예를 들어보자.

fruits = ['apple', 'banana', 'pear', 'strawberry', 'cherry']

print(fruits[1:3])
print(fruits[4:])
print(fruits[-3:-1])

# ['banana', 'pear']
# ['cherry']
# ['pear', 'strawberry']

fruits 리스트의 일부 엘리먼트들만 잘라서 사용하기 위해 리스트 슬라이스 연산인 fruits[1:3]을 사용했다. 이것의 의미는 1번 엘리먼트부터 3번 직전까지 엘리먼트들을 잘라서 복사해오겠다는 의미다.

리스트 슬라이스에서 콜론 뒤에 오는 두 번째 인덱스 값을 생략할 수도 있다. 두 번째 인덱스 값을 생략하면 리스트의 끝까지를 의미한다. 즉 [4:]는 4번 인덱스를 갖는 엘리먼트부터 시작해서 끝까지 나머지 모든 엘리먼트를 포함하겠다는 의미로 해석하면 된다.

리스트 슬라이스에서 음수도 사용할 수 있다. 음수를 사용하면 뒤에서 몇 번째부터 몇 번째까지를 자르겠다는 의미로 해석하면 된다. [-3:-1]은 뒤에서 세번째부터 뒤에서 첫번째 이전까지(뒤에서 첫번째는 포함안함) 잘라내겠다는 의미로 해석하면 된다.

리스트 엘리먼트 추가

리스트에 새로운 엘리먼트를 추가하고 싶을 때 list 자료형에서 제공하는 append() 메소드를 사용하면 된다.

fruits = ['apple', 'banana', 'pear', 'strawberry', 'cherry']

fruits.append('mango')
fruits.append('orange')

print(fruits)

# ['apple', 'banana', 'pear', 'strawberry', 'cherry', 'mango', 'orange']

리스트에 append()  메소드로 추가한 엘리먼트는 리스트의 맨 마지막 항목으로 추가된다. 다시 말하지만 리스트에는 꼭 일관된 데이터 타입이 담겨야하는 것은 아니기 때문에 숫자나 다른 리스트 같은 다른 타입의 데이터를 추가해도 된다.

다른 리스트에 있는 엘리먼트들을 추가하고 싶은 경우도 있다. 이 때는 extend() 메소드를 사용하면 된다.

fruits = ['apple', 'banana', 'pear']
new_fruits = ['strawberry', 'cherry']

fruits.extend(new_fruits)

print(fruits)

# ['apple', 'banana', 'pear', 'strawberry', 'cherry']

extend() 메소드의 인자로 준 리스트에 있는 엘리먼트들을 하나씩 리스트 자료형 객체에 추가해준다. 

새로운 엘리먼트를 리스트에 추가할 때 맨 뒤가 아닌 중간이나 특정 위치에 추가할 수도 있다. 리스트의 insert(a, b) 메소드를 이용하면 a위치에 b라는 엘리먼트를 추가한다.

fruits = ['apple', 'banana', 'pear', 'strawberry', 'cherry']

fruits.insert(2, 'mango')
fruits.insert(0, 'orange')

print(fruits)

# ['orange', 'apple', 'banana', 'mango', 'pear', 'strawberry', 'cherry']

예를 들어 insert(2, 'mango')를 실행하면 2번 인덱스 자리에 'mango' 엘리먼트를 추가한다. 만약 insert(0, 'orange')처럼 0번 인덱스를 주면 리스트의 맨 앞쪽에 엘리먼트를 추가하게 된다.

리스트 엘리먼트 삭제

리스트에서 엘리먼트를 삭제하려면 del 을 이용하면 된다. 

fruits = ['apple', 'banana', 'pear', 'strawberry', 'cherry']

del fruits[2]
del fruits[3]

print(fruits)

# ['apple', 'banana', 'strawberry']

del 뒤에 삭제하고자하는 리스트의 엘리먼트의 인덱스를 함께 지정해주면 리스트에서 지정된 엘리먼트를 삭제한다. del fruits[2]는 'pear'를 삭제한다. 그리고 난 다음 del fruits[3]은 'cherry'를 삭제한다. (원래는 strawberry지만 pear가 삭제된 이후 인덱스가 한 칸씩 땡겨졌으므로 del fruits[3]을 실행할 시점에는 cherry가 지워진다)

del 뒤에는 리스트 슬라이스가 올 수도 있다. 즉, 리스트의 특정 범위 값을 한번에 지우고 싶을 때 리스트 슬라이스를 이용해서 지울 엘리먼트를 지정할 수도 있다.

fruits = ['apple', 'banana', 'pear', 'strawberry', 'cherry']

del fruits[2:4]

print(fruits)

# ['apple', 'banana', 'cherry']

fruits[2:4]은 ['pear', 'strawberry']를 의미한다. 2번 인덱스는 포함하고 2번부터 4번 인덱스 직전까지를 의미하니까 pear와 strawberry를 나타낸다. 이걸 del로 지웠다.

리스트에는 remove() 메소드도 존재한다. remove() 메소드에 특정 값을 인자로 주면 리스트에서 그 값을 찾아서 제거해준다. 

fruits = ['apple', 'banana', 'pear', 'strawberry', 'cherry']

fruits.remove('banana')
fruits.remove('strawberry')

print(fruits)

# ['apple', 'pear', 'cherry']

remove()로 넘겨준 인자가 리스트에 여러번 중복해서 등장한다면 처음 등장한 엘리먼트 하나만 삭제된다. 만약 리스트에 없는 값을 지우라고 넘겨줬다면 ValueError가 발생한다. 

fruits = ['apple', 'banana', 'pear', 'strawberry', 'cherry', 'banana']

fruits.remove('banana')
print(fruits)

fruits.remove('grape')
print(fruits)

# ['apple', 'pear', 'strawberry', 'cherry', 'banana']
# Traceback (most recent call last):
#   File "./test.py", line 6, in <module>
#     fruits.remove('grape')
# ValueError: list.remove(x): x not in list

리스트에 있는 맨 마지막 값을 반환한 후에 리스트에서 삭제하는 pop() 메소드도 지원된다. 리스트를 이용해 스택(stack)을 구현할 때 append()와 함께 아주 편하게 사용할 수 있는 메소드다.

fruits = ['apple', 'banana', 'pear', 'strawberry', 'cherry', 'banana']

print(fruits.pop())
print(fruits.pop())
print(fruits.pop())

# banana
# cherry
# strawberry

만약 빈 리스트에서 pop() 메소드를 호출하면 IndexError가 발생한다.

fruits = list()

print(fruits.pop())

# Traceback (most recent call last):
#   File "./test.py", line 3, in <module>
#     print(fruits.pop())
# IndexError: pop from empty list

리스트 더하기 - list + list

파이썬에서 덧셈 연산은 다양하게 활용된다. 숫자 타입의 데이터에는 산술 연산 더하기로 사용되지만 문자열 타입에서는 두 문자열을 하나로 합치는 연산으로 사용된다. 리스트 자료형에서 더하기는 두 리스트를 하나로 합쳐주는 목적으로 사용된다.

your_fruits = ['apple', 'banana', 'pear']
my_fruits = ['strawberry', 'cherry']

fruits = your_fruits + my_fruits

print(fruits)

# ['apple', 'banana', 'pear', 'strawberry', 'cherry']

your_fruits와 my_fruits를 합쳐서 새로운 리스트 객체를 만들어 리턴한다. 리턴된 리스트를 fruits 변수에 담아서 활용했다.

리스트의 더하기 연산은 extend() 메소드와 유사하다. 하지만 더하기 연산은 새로운 리스트 객체를 생성해주는 반면 extend() 연산은 기존 리스트에 값을 추가한다는 점이 다르다.

리스트 곱하기 - list * n

리스트에는 곱하기 연산도 할 수 있다. 숫자 데이터에 대해서 곱하기 연산은 산술연산 곱셈을 의미한다. 리스트 자료형에 대한 곱하기 연산은 리스트를 n 번 반복해서 만들어준다는 의미다. 리스트에 2를 곱하면 리스트의 엘리먼트가 2번 반복되는 새로운 리스트를 만들고, 0을 곱하면 빈 리스트를 만들어서 리턴해준다.

my_fruits = ['apple', 'banana', 'pear']
fruits = my_fruits * 3
empty_fruits = my_fruits * 0

print(fruits)
print(empty_fruits)

# ['apple', 'banana', 'pear', 'apple', 'banana', 'pear', 'apple', 'banana', 'pear']
# []

리스트 길이 확인 - len

파이썬에서는 len()이라는 내장함수를 이용해서 리스트에 몇 개의 엘리먼트가 들어있는지 알 수 있다. 즉, len(리스트)를 호출하면 리스트의 길이를 반환해준다.

fruits = ['apple', 'banana', 'pear', 'strawberry', 'cherry']

print(len(fruits))

# 5

리스트 복사 - copy()

기존에 있는 리스트를 복사해서 새로운 리스트로 만들고 싶은 경우가 있다. 리스트 자료형에서 제공하는 copy() 메소드는 리스트에 있는 엘리먼트들을 복사해서 새로운 리스트로 만들어준다.

fruits = ['apple', 'banana', 'pear', 'strawberry', 'cherry', 'banana']

new_fruits = fruits.copy()
print(new_fruits)

# ['apple', 'banana', 'pear', 'strawberry', 'cherry', 'banana']

리스트 순서 뒤집기 - reverse()

리스트의 순서를 역순으로 바꾸고 싶은 경우 reverse() 메소드를 사용하면 된다.

fruits = ['apple', 'banana', 'pear', 'strawberry', 'cherry', 'banana']
fruits.reverse()
print(fruits)

# ['banana', 'cherry', 'strawberry', 'pear', 'banana', 'apple']

리스트 객체에 reverse() 메소드를 호출하면 리스트에 담겨 있는 엘리먼트들의 순서가 역순으로 바뀐다. 즉, 가장 마지막에 오는 엘리먼트가 가장 첫 번째 오도록 바뀌고, 뒤에서 두번째는 앞에서 두번째로... 이렇게 쭉 순서가 뒤집어진다.

리스트 정렬하기 - sort()

아마도 리스트의 순서를 변경하는 연산 중에 가장 많이 사용될 연산은 리스트의 정렬일 것이다. 리스트는 sort() 메소드를 이용해서 엘리먼트들을 정렬한다. 기본적으로는 오름차순으로 정렬된다.

fruits = ['apple', 'banana', 'pear', 'strawberry', 'cherry']
fruits.sort()
print(fruits)

# ['apple', 'banana', 'cherry', 'pear', 'strawberry']

리스트를 정렬하기 위해서는 리스트에 있는 엘리먼트들이 서로 비교 가능해야한다. 즉, 엘리먼트들의 데이터 타입이 같아야 한다. 만약 데이터 타입이 다른 엘리먼트가 있으면 TypeError가 발생한다.

fruits = ['apple', 'banana', 'pear', 'strawberry', 'cherry', 1]
fruits.sort()
print(fruits)

# Traceback (most recent call last):
#   File "./test.py", line 2, in <module>
#     fruits.sort()
# TypeError: '<' not supported between instances of 'int' and 'str'

만약 내림차순으로 정렬하고 싶다면 reverse 인자를 True로 설정하면 된다.

fruits = ['apple', 'banana', 'pear', 'strawberry', 'cherry']
fruits.sort(reverse=True)
print(fruits)

# ['strawberry', 'pear', 'cherry', 'banana', 'apple']

리스트 엘리먼트 개수 세기 - count()

리스트에는 중복된 엘리먼트가 여러개 포함될 수 있다. count() 메소드는 리스트에 포함되어 있는 엘리먼트 중에 인자로 받은 데이터와 같은 엘리먼트가 몇 개 있는지 확인하여 개수를 반환한다.

fruits = ['apple', 'banana', 'pear', 'strawberry', 'cherry', 'banana']

print(fruits.count('apple'))
print(fruits.count('banana'))

# 1
# 2

fruits 리스트에 apple은 한개 banana는 두개 들어있다. 따라서 count() 메소드에 각각을 인자로 넘기면 1과 2가 리턴된다. 만약 리스트에 존재하지 않는 엘리먼트를 인자로 줬다면 0이 리턴된다.

리스트 엘리먼트의 인덱스 확인 - index()

특정 엘리먼트가 리스트의 어디에 위치해있는지를 index() 메소드를 통해 알아낼 수 있다. index() 메소드의 인자로 넘긴 엘리먼트가 리스트의 몇 번째 인덱스에 있는지 리턴한다.

fruits = ['apple', 'banana', 'pear', 'strawberry', 'cherry', 'banana']

print(fruits.index('apple'))
print(fruits.index('banana'))

# 0
# 1

만약 인자로 넘긴 값이 리스트에 두개 이상 존재한다면 첫 번째 인덱스가 리턴된다. 

만약 리스트에 존재하지 않는 값을 인자로 넘긴 경우 ValueError가 발생한다.

fruits = ['apple', 'banana', 'pear', 'strawberry', 'cherry', 'banana']

print(fruits.index('mango'))

# Traceback (most recent call last):
#   File "./test.py", line 3, in <module>
#     print(fruits.index('mango'))
# ValueError: 'mango' is not in list

리스트 초기화 - clear()

리스트 내부에 존재하는 엘리먼트들을 모두 삭제하고 리스트를 초기화하기 위해서는 clear() 메소드를 사용하면 된다. 리스트 객체 자체는 그대로 남아있다. id도 같다. 그런 가운데 포함하고 있는 엘리먼트만 모두 삭제해준다.

fruits = ['apple', 'banana', 'pear', 'strawberry', 'cherry', 'banana']
fruits.clear()
print(fruits)

# []

clear() 메소드를 호출하면 리스트가 빈 리스트가 된다.

리스트에 엘리먼트가 존재하는지 확인

파이썬으로 프로그램을 작성하다보면 특정 값이 리스트에 존재하는지 확인하고 싶은 경우가 있다. 이 때, 리스트의 count() 메소드를 이용하거나 index() 메소드를 이용해서 Error가 발생하는지 여부를 확인하는 방법도 있지만 더 깔끔한 방법이 있다. 파로 파이썬이 제공하는 in (not in) 연산자를 이용한 방법이다.

'값 in 리스트'를 사용하면 입력한 값이 리스트에 있는지 조사해서 True, False를 리턴한다. 반대로 '값 not in 리스트'를 사용하면 입력한 값이 리스트에 없으면 True, 있으면 False를 리턴한다.

예를 들어보자.

fruits = ['apple', 'banana', 'pear', 'strawberry', 'cherry', 'banana']

if 'cherry' in fruits:
    print('체리는 fruits에 있음')

if 'mango' in fruits:
    print('망고는 fruits에 있음')
    
# 체리는 fruits에 있음

'cherry'는 fruits 리스트에 포함되어 있기 때문에 'cherry' in fruits가 True로 평가된다. 반면 'mango'는 fruits에 포함되어 있지 않기 때문에 'mango' in fruits는 False로 평가된다.

in 을 not in 으로 바꾸면 예상한대로 반대의 결과가 나온다.

fruits = ['apple', 'banana', 'pear', 'strawberry', 'cherry', 'banana']

if 'cherry' not in fruits:
    print('체리는 fruits에 있음')

if 'mango' not in fruits:
    print('망고는 fruits에 있음')
    
 # 망고는 fruits에 있음

리스트 엘리먼트 순회

리스트에 포함되어 있는 엘리먼트 들을 하나씩 순회하면서 어떤 작업을 하고 싶은 경우 for 문을 사용하면 된다. 예를 들어

fruits = ['apple', 'banana', 'pear', 'strawberry', 'cherry', 'banana']

for f in fruits:
  print(f)
  
# apple
# banana
# pear
# strawberry
# cherry
# banana

 

파이썬 스크립트 작성에 도움되는 글 모음

파이썬으로 프로그램을 작성할 때 도움되는 글들을 모아본다. 개발환경 [Python] macOS에 파이참 설치 [Python] 파이참 깃허브 연동 [Python] 파이썬 PIP란? [Python] VSCode를 이용한 개발환경 [Python] python3..

hbase.tistory.com

 

[Python] 집합 (set) 자료형 사용법 및 예제

파이썬 2.3부터 '집합(set)' 자료형이 지원되기 시작했다. set은 집합과 관련된 연산들을 쉽게 처리하기 위해 제공하는 자료형이다. 특히 파이썬 프로그램에서 중복된 값을 제거하기 위해서 많이

hbase.tistory.com

 

[Python] 튜플(tuple) 자료형 사용법 및 예제

파이썬의 튜플은 여러 데이터를 묶어서 같이 처리할 수 있게 해주는 자료형 중 하나다. 위키백과에서 설명하는 튜플은 "셀 수 있는 수랴의 순서 있는 열거"다. 튜플은 리스트와 거의 유사하게 사

hbase.tistory.com

 

[Python] 딕셔너리(dict) 자료형 사용법 및 예제

파이썬은 '딕셔너리(Dictionary)'라고 하는 자료형을 제공한다. 다른 언어에서는 '해시(Hash)', '연관배열(Associative Array)' 혹은 '맵(Map)' 등으로 불리는 자료형이다. 이 자료형은 Key 값과 그 Key 값에 특

hbase.tistory.com

 

댓글