6 분 소요

리스트 (list)

파이썬에는 배열 구조(sequence structure)를 가지는 개체들이 있는데, 그 중 두 개로 list, tuple이 있다. 이 둘 모두 여러 개의 요소 또는 아무런 요소를 가지지 않을 수 있다. 들어갈 요소들은 각기 다른 종류의 자료형이여도 된다. 즉, 파이썬의 개체라면 어떤 것이든 들어갈 수 있다.

tuple은 immutable, list는 mutable 자료형이다.

list 생성

empty_list = []

week = ['월', '화', '수', '목', '금', '토', '일']
favorite_foods = ['hamburger', 'chicken', 'zero coke']
numbers = [1, 2, 3, 4, 5]

또는 list() 함수를 이용하여 빈 list를 만들 수도 있다.

empty_list = list()
print(empty_list)
[]

list 요소 내에는 중복되는 요소를 넣어도 된다.

list() 함수를 이용하여 다른 자료형을 list로 바꾸기

some_string = 'dogs'
to_list = list(some_string)
print(to_list)
['d', 'o', 'g', 's']

이 외에도 tuple도 list로 바꿀 수 있음

추측) string, tuple, set처럼 배열 자료형만 가능한 것 같음

[offset]으로 요소 추출하기

0부터 시작하는 offset을 리스트[offset], 즉 대괄호 안에 대입함으로써 리스트 내 해당 요소를 추출할 수 있다.

some_list = [3, 3, 1]
print(some_list[0])
print(some_list[1])
print(some_list[2])
3
3
1

이 때 인덱스는 0부터 (리스트 내의 총 요소의 수 - 1)까지만 유효하다. 이를 넘어서면 에러 발생

[offset]으로 요소 바꾸기

list 내의 요소를 바꾸는 것도 가능하다

some_list = ['지금은', '몇시', '몇분']
some_list[1] = '몇날'
print(some_list)
['지금은', '몇날', '몇분']

list slice

list 내 부분 배열을 slice를 이용하여 추출해낼 수 있다.

some_list = ['지금은', '몇시', '몇분']
print(some_list[0:2])
['지금은', '몇시']

append() 함수를 이용해 리스트 끝에 요소 추가하기

some_list = ['지금은', '몇시', '몇분']
some_list.append('몇초')
print(some_list)
['지금은', '몇시', '몇분', '몇초']

list 병합

list를 또 다른 list에 하나로 합칠 수 있다. 방법은 두 가지.

  1. extend() 함수 이용
some_list = ['지금은', '몇시', '몇분']
other_list = ['오후', '열시', '정각']
some_list.extend(other_list)
print(some_list)
print(other_list)
['지금은', '몇시', '몇분', '오후', '열시', '정각']
['오후', '열시', '정각']

list A, B가 있을 때, A.extend(B)는 list A의 뒤에 B가 추가되어 다시 하나의 list로 반환된다.

  1. += 기호 이용
some_list = ['지금은', '몇시', '몇분']
other_list = ['오후', '열시', '정각']
some_list += other_list
print(some_list)
print(other_list)
['지금은', '몇시', '몇분', '오후', '열시', '정각']
['오후', '열시', '정각']

만약 append()를 사용했다면???

some_list = ['지금은', '몇시', '몇분']
other_list = ['오후', '열시', '정각']
some_list.append(other_list)
print(some_list)
print(other_list)
['지금은', '몇시', '몇분', ['오후', '열시', '정각']]
['오후', '열시', '정각']

other_list가 some_list의 하나의 요소로 삽입됨을 확인할 수 있다.

insert() 함수를 이용하여 중간에 요소 삽입하기

append() 함수는 추가 요소를 리스트의 맨 끝에만 추가할 수 있었다. 리스트의 요소들 중간에 요소를 추가하고자 한다면 insert()를 이용할 수 있다.

사용법: list.insert(index, 삽입하고자 하는 인수)

some_list = ['지금은', '몇시', '몇분']
some_list.insert(1, "오후")
print(some_list)
['지금은', '오후', '몇시', '몇분']

이 때 인덱스가 (list 내의 총 요소의 개수 - 1)를 넘으면 에러 대신 append()처럼 맨 마지막에 해당 요소를 삽입해준다.

some_list = ['지금은', '몇시', '몇분']
some_list.insert(10, "오후")
print(some_list)
['지금은', '몇시', '몇분', '오후']

del을 이용하여 list 요소 삭제하기

del list[index] 를 이용하여 list 내의 해당 index를 가지는 요소를 삭제한다.

some_list = ['지금은', '몇시', '몇분']
print(some_list[1])
del some_list[1]
print(some_list[1])
print(some_list)
몇시
몇분
['지금은', '몇분']

리스트 중간 요소가 삭제되었다면 그 뒤에 있던 요소들이 앞당겨져 온다.

위 예제에서 리스트의 두 번째 요소인 ‘몇시’가 삭제된 후 그 뒤에 있던 요소들이 앞당겨져서 지금은 두 번째 요소에 ‘몇분’이라는 요소가 자리잡게 된다.

  • del은 파이썬 구문(statement)이지 list의 method가 아니다. del은 할당(=)의 반대 역할을 한다고 볼 수 있다. 파이썬 객체로부터 이름을 떼서 그 객체의 메모리를 자유롭게 해준다.

remove()를 이용하여 list 요소 삭제하기

사용법: list.remove(list 내에 있는 인수)

some_list = ['지금은', '몇시', '몇분', '몇초']
some_list.remove('지금은')
print(some_list)
['몇시', '몇분', '몇초']

pop()을 이용하여 요소를 추출하고 삭제하기

pop()은 리스트 내 한 요소를 추출한 뒤 리스트 내에 있는 그 요소를 삭제시키는 동작을 동시에 해준다.

사용법: pop(index)

pop(0)은 리스트의 첫 요소를 반환하고 삭제하고, pop() 또는 pop(-1)은 리스트의 마지막 요소를 반환한 뒤 삭제한다.

some_list = ['지금은', '몇시', '몇분', '몇초']

temp_var1 = some_list.pop()
print(some_list)
print(temp_var1)

temp_var2 = some_list.pop(1)
print(some_list)
print(temp_var2)
['지금은', '몇시', '몇분']
몇초
['지금은', '몇분']
몇시

append()를 이용하여 리스트에 요소를 추가한 뒤 pop()을 이용해 마지막 요소를 삭제한다면 이는 stack 또는 LIFO(last in, first out)이라고 불리는 자료구조(data structure)에 해당한다.

cabinet = ['첫 번째 수건', '두 번째 수건', '세 번째 수건']

cabinet.append('네 번째 수건')  # 네 번째 수건 빨래를 완료하여 캐비넷에 넣었다.
i_wanna_wash_my_hand = cabinet.pop()

print("손 씻기 위해 서랍 제일 위에 있는 수건을 가져다 썼어요.")
print("그게 몇 번째 수건이었나요? {}이었어요.".format(i_wanna_wash_my_hand))
print("지금 서랍장에 남은 수건들의 현황은? :", cabinet)
 씻기 위해 서랍 제일 위에 있는 수건을 가져다 썼어요.
그게  번째 수건이었나요?  번째 수건이었어요.
지금 서랍장에 남은 수건들의 현황은? : ['첫 번째 수건', '두 번째 수건', '세 번째 수건']

index()로 list 내 요소의 index 찾기

animal = ['monkey', 'lion', 'snake', 'cat']
print(animal.index('lion'))
1

find()는 문자열에서 쓰이는 함수이다. 리스트에는 쓸 수 없다. (쓰면 에러남)

in으로 list 내 해당 요소가 있는지 확인하기

사용법: 요소 in list

반환값: boolean (True or False)

해당 요소가 list 내에 있으면 True, 없으면 False 반환

animal = ['monkey', 'lion', 'snake', 'cat']

print('snake' in animal)
print('dog' in animal)
True
False

count()로 list 내 요소들의 개수 세기

list 내에 어떤 특정 요소들이 몇 개 있는지 확인하기 위해 count() 함수를 쓸 수 있다.

animal = ['monkey', 'lion', 'snake', 'cat', 'cat', 'lion', 'cat']

print(animal.count('monkey'))
print(animal.count('cat'))
print(animal.count('dog'))
1
3
0

sort(), sorted()를 이용하여 list 내 요소들 순서 재배치하기

list 내 요소들을 순서대로 정리하기 위한 함수 두 가지

  1. sort() : list 내 순서를 바꾼다. list 자체의 순서가 바뀐다.
    1. 사용법: list.sort() → sort()는 list의 함수
  2. sorted() : list 내 순서를 바꾼 복사본을 반환한다. list 자체는 그대로이다.
    1. 사용법: sorted(list) → sorted()는 list의 함수가 아닌 일반적인 함수

list 내 요소들이 모두 숫자인 경우 기본적으로 오름차순으로, 알파벳인 경우 알파벳 순서로 정렬해준다.

animal = ['monkey', 'lion', 'snake', 'cat', 'cat', 'lion', 'cat']

sorted_animal = sorted(animal)
print(sorted_animal)
print(animal)

animal.sort()
print(animal)
['cat', 'cat', 'cat', 'lion', 'lion', 'monkey', 'snake']
['monkey', 'lion', 'snake', 'cat', 'cat', 'lion', 'cat']
['cat', 'cat', 'cat', 'lion', 'lion', 'monkey', 'snake']

실행결과의 첫 번째 줄은 sorted()를 이용한 결과이고, 두 번째 줄은 원래 list를 출력한 것이다. 보면 알겠지만 sorted() 함수는 원래 list를 복사하여 정렬하므로 원래 list가 변하지 않는다. 그러나 sort()함수는 원래 list 자체를 정렬시킨다.

한글도 잘 정렬될까?

animal = ['원숭이', '사자', '수달', '개', '고양이', '낙타', '라마']

sorted_animal = sorted(animal)
print(sorted_animal)
print(animal)

animal.sort()
print(animal)
['개', '고양이', '낙타', '라마', '사자', '수달', '원숭이']
['원숭이', '사자', '수달', '개', '고양이', '낙타', '라마']
['개', '고양이', '낙타', '라마', '사자', '수달', '원숭이']

잘 된다.

list 내에 서로 다른 자료형의 요소들이 있어도 sort()와 sorted()를 사용할 수 있는 경우가 있다.

numbers = [7, 1.5, 3, 12]

sorted_numbers = sorted(numbers)
print(sorted_numbers)

numbers.sort()
print(numbers)
[1.5, 3, 7, 12]
[1.5, 3, 7, 12]

연산 과정에서 자동으로 형변환이 일어났기에 가능했다.

오름차순이 아닌 내림차순으로 정렬하고자 한다면 다음의 인수를 대입한다.

  • list.sort(reverse=True)
  • sorted(list, reverse=True)
numbers = [7, 1.5, 3, 12]

sorted_numbers = sorted(numbers, reverse=True)
print(sorted_numbers)

numbers.sort(reverse=True)
print(numbers)
[12, 7, 3, 1.5]
[12, 7, 3, 1.5]

len() 으로 list 길이(list 내 요소들의 총 개수) 반환하기

animal = ['원숭이', '사자', '개', '고양이', '수달']
print(len(animal))
5

list 복사하기

list가 할당된 변수 A를 변수 B에 할당했을 때 둘 중 하나의 list 속 요소 내용이 달라지면 다른 list도 똑같이 달라진다.

animal = ['원숭이', '사자', '개', '고양이', '수달']
zoo = animal

print(animal)
print(zoo)

animal[1] = '호랑이'
print(animal)
print(zoo)
['원숭이', '사자', '개', '고양이', '수달']
['원숭이', '사자', '개', '고양이', '수달']
['원숭이', '호랑이', '개', '고양이', '수달']
['원숭이', '호랑이', '개', '고양이', '수달']

위 예제에서 animal 변수에 할당된 list 속 ‘사자’라는 요소를 ‘호랑이’로 바꿨을 때 zoo 변수에 할당된 list도 똑같이 변한 것을 확인할 수 있다. 이전에 변수를 다뤘던 장에서 언급했듯, animal과 zoo는 똑같은 list 객체를 참조한 것일 뿐이다. (그래서 실제로 복사되었다고 말하긴 어렵다) 즉 하나의 상자에 그 상자의 별명이 두 개인 것일 뿐이다. 그래서 그 상자 속 내용이 바뀌면 두 별명 중 어떤 걸 참조해도 바뀐 내용을 참조할 것이다.

그렇다면 서로 독립적으로 쓸 수 있도록 list를 복사하려면 어떻게 해야될까?

다음의 3가지 방법이다.

  1. list 함수 copy() 이용
  2. list() 함수 이용
  3. list slice [:] 이용
animal = ['원숭이', '사자', '개', '고양이', '수달']
zoo1 = animal.copy()
zoo2 = list(animal)
zoo3 = animal[:]

print(zoo1)
print(zoo2)
print(zoo3)
['원숭이', '사자', '개', '고양이', '수달']
['원숭이', '사자', '개', '고양이', '수달']
['원숭이', '사자', '개', '고양이', '수달']

세 가지 방법을 이용해 복사된 list를 할당받은 위 예제의 세 변수 zoo1, zoo2, zoo3은 서로 독립적으로 복사되었다. 그래서 각각 내용을 바꿔도 다른 list에 영향을 미치지 않는다.

animal = ['원숭이', '사자', '개', '고양이', '수달']
zoo1 = animal.copy()
zoo2 = list(animal)
zoo3 = animal[:]

animal[2] = 3
zoo2[3] = '앵무새'

print(animal)
print(zoo1)
print(zoo2)
print(zoo3)
['원숭이', '사자', 3, '고양이', '수달']
['원숭이', '사자', '개', '고양이', '수달']
['원숭이', '사자', '개', '앵무새', '수달']
['원숭이', '사자', '개', '고양이', '수달']

Reference

[1] Bill Lubannovic, “Introducing Python”, (O’REILLY, 2015)


  • .

      animal = ['원숭이', '사자', '개', '고양이', '술에 만취한 나', '수달']
      print(animal.count('개'))
    
      2
    

    어? 버근가?

    아, 아닌가?

This content is licensed under CC BY-NC 4.0

댓글남기기