티스토리 뷰

Basic

파이썬 List

nickas 2020. 4. 12. 15:23

파이썬 자료구조 형태의 하나로 시퀀스 데이터를 가지고 있음.
시퀀스는 데이터의 순서를 정하는 것을 의미 하므로 순서를 가지고 있고 index를 사용하여 값을 가져 올 수 있음.

보통 list는 원하는 데이터를 하나의 변수로 정의하여 사용하기 위해 사용.

예를 들어

>>> animal = ['dog', 'cat', 'monkey']
>>> numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

와 같이 의미가 같은 값들을 하나의 변수로 묶어 사용할 수 있다.

List 만들기

>>> a = []      # 빈 list 생성 
>>> b = list()  # built-in 함수를 사용
>>> c = [1, 2, 3, 4]
>>> c
[1, 2, 3, 4]
>>> d = ['a', 'b', 'c', 'd']
>>> d
['a', 'b', 'c', 'd']
>>> type(d)
list

>>> e = [1, 'a', 2, 'b']  # 다른 타입을 혼합할 수 있음.
>>> e
[1, 'a', 2, 'b']

List 안의 값 사용하기

indexing

indexing 값을 이용하여 값을 추출 할 수 있음.

>>> a = [1, 2, 3, 4]
>>> a[0]
1
>>> a[-1]  # 마직막 값을 반환
4

slicing

[start:end:step] 형식을 사용

>>> a = [1, 2, 3, 4]
>>> a[1:-1]
[2,3]
>>> a[2:]
[3, 4]
>>> a[:-1]
[1, 2, 3]
>>> a[::2]
[1, 3]

List 연산

>>> a = [1, 2, 3]
>>> b = [4, 5, 6]
>>> a + b
[1, 2, 3, 4, 5, 6]

>>> a * 3
[1, 2, 3, 1, 2, 3, 1, 2, 3]

중첩 리스트 만들기

리스트 내에 리스트를 만들 수 있음.
중첩 갯수는 거의 제한이 없음.(많은 수의 중첩은 거의 사용하지 않음, 계산하기 어려우니까)

>>> a = [[]]
>>> b = [1, [2, 3]]
>>> c = [{}]
>>> d = [1, {1: 'a', 2: 'b'}]  # List 안에 Dictionary를 삽입할 수 있음.
>>> e = [1, [2, [3, 4]]]

중첩 리스트 안의 값 사용하기

>>> a = [1, [2, 3]]
>>> a  
[1, [2, 3]]  # 첫 번째 리스트의 index 0, 1에 값이 들어 있는 형태
>>> a[1]
[2, 3]       # 첫 번째 리스트의 index 1에 있는 값 추출
>>> a[1][0]  # 첫 번째 리스트의 index 1에 있는 값 추출 후 두 번째 리스트의 index 0에 있는 값 추출.
2

>>> a = [1, [2, [3]]]
>>> a[1][1][0]
3

List에 값 추가하기

.append()

List의 맨 뒤부터 값을 추가

>>> a = []
>>> a.append(1)
>>> a
[1]

.insert()

원하는 위치에 값 삽입

>>> a = [1, 2, 4]
>>> a.insert(2, 3)  # .insert(index, value)
>>> a
[1, 2, 3, 4]

slicing 사용하여 추가

>>> a = [1, 2, 5, 6]
>>> a[2:2] = [3, 4]
>>> a
[1, 2, 3, 4, 5, 6]

.extend()

listlist에 추가 할 때 중첩된 list 형태로 추가하지 않기 위해 사용

>>> a = [1, 2, 3]
>>> b = [4, 5, 6]
>>> a.append(b)
>>> a
[1, 2, 3, [4, 5, 6]]  # 중첩되어 추가됨

>>> a = [1, 2, 3]
>>> a.extend(b)
>>> a
[1, 2, 3, 4, 5, 6]  # 중첩되지 않음

>>> a + b           # 같은 결과
[1, 2, 3, 4, 5, 6, 4, 5, 6]

List 값 교체하기

indexing 사용하여 교체

>>> a = [1, 2, 3]
>>> a[0] = 4
>>> a
[4, 2, 3]

slicing 사용하여 교체

>>> a = [1, 2, 3, 4]
>>> a[1:3] = [5, 6, 7]
>>> a
[1, 5, 6, 7, 4]

List의 값 지우기

.pop()

.pop() 메서드를 사용하면 값이 추출되고 리스트에서 삭제가 됨.

>>> a = [1, 2, 3, 4]
>>> a.pop()   # 마지막 값이 추출 됨
4
>>> a
[1, 2, 3]
>>> a.pop(0)  # index 사용
1

List의 특정 값 지우기

.remove() 메서드 사용

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

>>> b = [1, 2, 3, 4, 1]
>>> b.remove(1)  # 값이 하나 이상일 경우, 첫 번째 값이 삭제됨 
>>> b
[2, 3, 4, 1]

del 사용하여 지우기

>>> a = [1, 2, 3, 4]
>>> del a[0]
>>> a
[2, 3, 4]

>>> a = [1, 2, 3, 4]
>>> del a[1:3]
>>> a
[1, 4]

slicing 사용하여 지우기

>>> a = [1, 2, 3, 4]
>>> a[1:3] = []
>>> a
[1, 4]

List의 모든 값 지우기

.clear() 메서드 사용

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

List membership 확인

>>> a = [1, 2, 3, 4]
>>> 1 in a
True
>>> 5 in a
False

List Iteration

>>> a = [1, 2, 3, 4]
>>> for i in a:
        print(i, end=' ')
1 2 3 4

다른 List 메서드

.count()

list 값의 갯수를 반환

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

.index()

list 값의 인덱스를 확인하기 위해 사용

>>> a = [1, 2, 3]
>>> a.index(1)
0

.reverse()

list 값을 거꾸로 나열

>>> a = [1, 2, 3]
>>> a.reverse()
>>> a
[3, 2, 1]              # list 값의 위치가 변함

>>> a = [1, 2, 3]
>>> list(reversed(L))  # reversed() built-in 함수를 이용
[3, 2, 1]
>>> a
[1, 2, 3]              # list 값의 위치가 변하지 않음

.sort()

list 값을 정렬

>>> a = ['b', 'd', 'c']
>>> a.sort()
>>> a
['b', 'c', 'd']

>>> a = [4, 7, 9, 1]
>>> a.sort()
>>> a
[1, 4, 7, 9]

>>> a = ['a', 'A', 'b' 'B']  # 대문자 먼저
>>> a.sort()
>>> a 
['A', 'B', 'a', 'b']

.sort()에 정렬 기준 주기

>>> a = ['a', 'b', 'A', 'B']
>>> a.sort(key=str.lower)  # 문자를 소문자로 변환 후 정렬
>>>a
['a', 'A', 'b', 'B']

>>> a = ['a', 'b', 'A', 'B']
>>> a.sort(key=str.lower, reverse=True)  # 거꾸로 정렬
['b', 'B', 'a', 'A']

sorted() built-in 함수를 사용할 수 있음.

>>> a = ['a', 'b', 'A', 'B']
>>> sorted(a, key=str.lower, reverse=True)
['b', 'B', 'a', 'A']

>>> sorted([x.lower() for x in a], reverse=True)  # List Comprehension를 이용하여 새로운 list를 만들어 사용
['b', 'b', 'a', 'a']

더 알아보기

List를 만드는 다른 방법

range() built-in 함수를 사용하여 연속된 숫자로 List 생성

>>> a = list(range(5)  
>>> a
[0, 1, 2, 3, 4]

map() built-in 함수를 사용하여 기존 list와 다른 새로운 list를 생성

>>> list(map(abs, [-1, -2, 0, 1, 2]))
[1, 2, 0, 1, 2]

Stack 만들기

LIFO(Last-in-first-out) stack 구조를 만들 수 있음.

>>> L = []
>>> L.append(1)  # stack에 값 넣기
>>> L.append(2)
>>> L
[1, 2]
>>> L.pop().     # 마지막으로 입력된 값 꺼내기
2
>>> L
[1]

List Copy

용어 그대로 list를 복사하는 방법

잘못된 사용(주의)

>>> a = [1, 2, 3]
>>> b = a
>>> b
[1, 2, 3]

위와 같이 변수 a를 변수 b에 대입하면 같은 값을 가져오는 것 처럼 보여 복사된거 처럼 보이지만 사실은 위의 그림에서 보는 것과 같이 같은 객체 정보를 참조하는 것으로 list의 값이 변경될 경우 변수 b의 값도 같이 변경되서 보임.

>>> id(a)
4501679424
>>> id(b)
4501679424  # 같은 메모리 주소를 가짐
>>> a.append(4)
>>> a
[1, 2, 3, 4]
>>> b
[1, 2, 3, 4]

위의 예시 처럼 변수 a와 b는 같은 객체를 참조하기 때문에 의도적으로 같은 값을 가지는 것이 아닌 각각 별개의 값을 가지길 원할 때 위와 같은 방법을 사용 시 프로그램에 심각한 오류를 초래할 수 있음.

파이썬에서 대입(=)이란 변수에 값을 저장하는 것이 아닌 오브젝트의 메모리 주소를 저장하는 것을 의미

바른 사용

얕은 복사(Shallow copy)

>>> a = [1, 2, 3, 4]
>>> b = a[:]      # 얕은 복사
>>> c = list(a)   # 다른 방법
>>> d = a.copy()  # 또 다른 방법
>>> id(a)
4497110784
>>> id(b)
4501298944  # 메모리 주소가 다름
>>> id(c)
4498557632
>>> id(d)
4501296640
>>> a.append(5)
>>> a
[1, 2, 3, 4, 5]
>>> b
[1, 2, 3, 4]  # 값 변하지 않음
>>> c
[1, 2, 3, 4]
>>> d
[1, 2, 3, 4]

주의사항

위의 방법으로 복사가 되었지만 주의사항이 있음. 리스트 값 중에 mutable(가변) 값이 있고 그 값이 변경되면 복사된 모든 리스트에 적용됨. 예를들어 위의 예시를 보면 복사를 통해서 리스트가 새로 만들어 졌지만 위 그림을 보면 각 리스트의 같은 index 값들은 같은 int 클래스의 인스턴스 오브젝트 주소 정보를 참조하고 있음. 그러나 integerstring은 immutable(불변)의 값 이기 때문에 아래와 같이 변수 a 리스트에서 값을 변경해도 다른 리스트에는 영향이 없음

>>> a[0] = 5  # 새로운 int 인스턴스가 만들어지고 index 0이 새로운 인스턴스 주소 값을 가짐.
>>> a
[5, 2, 3, 4]  
>>> b 
[1, 2, 3, 4]  # 변경되지 않음
>>> c
[1, 2, 3, 4]
>>> d 
[1, 2, 3, 4]

그러나 아래와 같이 리스트안에 리스트(중첩 리스트)가 존재할 경우 리스트는 mutable이기 때문에 값이 변경되면 복사된 모든 리스트에 적용이 됨.

>>> a = [1, [2, 3]]
>>> b = a[:]
>>> c = list(a]
>>> d = a.copy()
>>> a
[1, [2, 3]]
>>> b
[1, [2, 3]]
>>> c
[1, [2, 3]]
>>> d
[1, [2, 3]]

>>> a[1].append(4)  # 중첩된 리스트 값 변경
>>> a
[1, [2, 3, 4]]
>>> b 
[1, [2, 3, 4]]  # 다른 리스트에 영향 받음
>>> c
[1, [2, 3, 4]]
>>> d
[1, [2, 3, 4]]

즉 얕은 복사라는 단어 답게 표면적인 부분만 복사가 이루어 지고 내부는 복사가 안됨. 이러한 문제를 해결하기 위해 깊은 복사를 사용.

깊은 복사(Deep copy)

copy 모듈의 deepcopy를 사용.

>>> import copy
>>> a = [1, [2, 3]]
>>> b = copy.deepcopy(a)
>>> id(a)
4493449024
>>> id(b)
4497513408
>>> a
[1, [2, 3]]
>>> b
[1, [2, 3]]
>>> a[1].append(4)
>>> a
[1, [2, 3, 4]
>>>b
[1, [2, 3]]

위 그림 처럼 깊은 복사를 사용하면 중첩된 리스트도 새로운 리스트가 만들어 지면서 복사가 되고 복사된 리스트 끼리 영향을 주지 않은다.

List comprehensions

List comprehension을 이용하면 코드 한줄로 list를 생성할 수 있고, 생성 속도도 더 빠르기 때문에 큰 데이터를 사용하여 list를 생성 시 사용하면 이점을 얻을 수 있음.

>>> res = [c for c in 'spam']
>>> res
['s', 'p', 'a', 'm']

# list를 만드는 같은 방법
>>> res = []
>>> for c in 'spam':
        res.append(c)
>>> res
['s', 'p', 'a', 'm']

'Basic' 카테고리의 다른 글

Set  (0) 2020.04.25
파이썬 Tuple  (0) 2020.04.19
파이썬 Dictionary  (0) 2020.04.19
파이썬 String  (0) 2020.04.11
파이썬 변수  (0) 2020.04.05
최근에 올라온 글
글 보관함