2.7. 리스트

리스트(list) 는 가변적이고 순서가 있는 값의 시퀀스입니다. 문자열이나 바이트와 달리 리스트는 어떤 타입의 값이든 담을 수 있으며, 항목을 제자리에서 변경, 추가, 제거할 수 있습니다.

2.7.1. 리스트 만들기

대괄호로 리스트 리터럴을 만듭니다:

empty   = []
nums    = [1, 2, 3]
mixed   = [1, "two", 3.0, True, None]    # any types
nested  = [[1, 2], [3, 4], [5, 6]]       # lists of lists

list 생성자는 어떤 이터러블로부터든 리스트를 만듭니다:

>>> list("abc")
['a', 'b', 'c']
>>> list(range(5))
[0, 1, 2, 3, 4]

2.7.2. 길이, 인덱싱, 슬라이싱

len() 은 항목의 개수를 반환합니다. 인덱싱과 슬라이싱은 문자열과 동일하게 작동합니다. 위치는 0에서 시작하고, 음수 인덱스는 끝에서부터 세며, 유효 범위를 벗어난 슬라이스는 예외를 발생시키지 않고 조용히 잘립니다:

>>> nums = [10, 20, 30, 40, 50]
>>> len(nums)
5
>>> nums[0]
10
>>> nums[-1]
50
>>> nums[1:4]
[20, 30, 40]
여섯 개 셀로 이루어진 리스트로, 각 셀 위에 양수 인덱스 0..5, 아래에 음수 인덱스 -6..-1 이 표시되어 있습니다.

양수 인덱스는 앞에서부터 세고, 음수 인덱스는 끝에서부터 셉니다.

슬라이스 구문은 Python이 내부적으로 만드는 slice 객체의 축약형입니다. nums[1:4]nums[slice(1, 4)] 와 같습니다. 직접 만들 일은 드물지만, slice() 는 슬라이스를 값으로 저장해 재사용할 때 가끔 유용합니다:

head = slice(0, 3)
print(nums[head])             # [10, 20, 30]
print(letters[head])          # first three letters, same slice

2.7.3. 리스트 변경하기

리스트는 인덱스와 슬라이스를 통한 제자리 할당을 지원합니다:

>>> nums = [10, 20, 30]
>>> nums[0] = 99
>>> nums
[99, 20, 30]
>>> nums[1:3] = [200, 300, 400]    # slice can change the length
>>> nums
[99, 200, 300, 400]

가장 자주 쓰이는 리스트 메서드:

  • list.append() – 끝에 항목 하나를 추가합니다.

  • list.extend() – 이터러블의 모든 항목을 덧붙입니다.

  • list.insert() – 지정한 위치에 삽입합니다.

  • list.remove() – 어떤 값의 첫 번째 출현을 삭제합니다.

  • list.pop() – 항목을 제거하고 반환합니다(기본은 마지막 항목).

  • list.clear() – 모든 항목을 제거합니다.

  • list.sort() – 제자리에서 정렬합니다. 내림차순을 원하면 reverse=True 를 전달하세요.

  • list.reverse() – 제자리에서 뒤집습니다.

>>> nums = []
>>> nums.append(1)
>>> nums.extend([2, 3])
>>> nums.insert(0, 99)
>>> nums
[99, 1, 2, 3]
>>> nums.pop()
3
>>> nums.sort()
>>> nums
[1, 2, 99]

이 메서드들은 리스트를 제자리에서 변경하고 None 을 반환합니다. 다음과 같이 작성하는 것은

nums = nums.sort()    # nums is now None -- common bug

원하는 결과가 거의 아닙니다. 원본 nums 는 정렬되었지만, 그 할당이 이름을 반환값으로 덮어써 버립니다. nums.sort() 를 별도의 줄에서 호출하거나, 내장 함수 sorted() 를 사용해 원본을 변경하지 않고 새로 정렬된 리스트를 돌려받으세요.

2.7.4. 연산자

  • + 는 두 리스트를 새 리스트로 연결합니다.

  • * 는 리스트를 반복합니다.

  • in 은 멤버십을 검사합니다.

>>> [1, 2] + [3, 4]
[1, 2, 3, 4]
>>> [0] * 5
[0, 0, 0, 0, 0]
>>> 3 in [1, 2, 3]
True

2.7.5. 리스트 반복하기

for 루프는 항목을 순서대로 훑습니다:

for n in [10, 20, 30]:
    print(n)

2.7.6. 별칭과 변경

리스트는 메모리상의 단일 값이며, 여러 이름이 같은 리스트를 가리킬 수 있습니다. 한 이름을 통해 변경하면 같은 리스트를 가리키는 다른 모든 이름에서도 그 변경이 보입니다.

변수 a와 b가 둘 다 같은 리스트 객체를 가리키고 있으며, a에 항목을 추가하면 b를 통해서도 보입니다.

ab 는 둘 다 같은 리스트를 가리킵니다. 어느 이름을 통해 변경하든 다른 모든 이름이 보는 내용이 바뀝니다.

>>> a = [1, 2, 3]
>>> b = a
>>> a.append(4)
>>> b
[1, 2, 3, 4]                # same object, change is visible

독립적인 복사본을 만들려면 리스트 전체를 슬라이싱하거나 list 생성자를 호출하세요:

>>> c = a[:]                # or list(a)
>>> a.append(5)
>>> c
[1, 2, 3, 4]                # c is unaffected

이것은 최상위 리스트만 복사합니다. 중첩된 리스트는 여전히 원본과 복사본 사이에서 공유됩니다.