본문 바로가기
  • 시 쓰는 개발자
알고리즘/코테 스터디 (2024)

코테 문법정리 (2) - 리스트 [ ] ★★★

by poetDeveloper 2024. 3. 15.

자료형은 잘 알아두어야 한다. 자료형에 따라 쓰는 함수도 다르고 처리 방식도 달라지니 조심하자.

 

리스트 ★★★

  • 내부적으로 배열이다.
  • 가변 객체이다. (가변 : 리스트, 셋, 딕셔너리 / 불변 : 문자열, 튜플, 수 자료형)
  • 연결리스트라서 append(), remove() 등 사용 가능
  • 배열 혹은 테이블이라고 부르기도 함.

리스트 초기화 방법

a = [1,2,3,4,5] # 직접 값을 넣어서 초기화할 수 있다.

a = list() # 빈 리스트 만들기 (1)

a = [] # 빈 리스트 만들기 (2)

 

TIP - 모든 값 0으로 초기화 하기

n = 5
a = [0]*n # [0,0,0,0,0]

이런식으로 크기가 N이고, 모든 값이 0인 1차원 리스트를 초기화 할 수 있다.

 

리스트 인덱싱

  • 인덱스에 -1을 넣으면 맨 뒤에 값을 가져올 수 있다.
  • 할당으로 리스트 값을 바꿀 수도 있다.
a = [1,2,3]
a[-1] # 3

a[1] = 10
a # [1,10,3]

 

리스트 슬라이싱 a[시작:끝-1]

a = [1,2,3,4,5]

a[1:3] # [2,3]

a[:3] # [1,2,3]

a[3:] # [4,5]

 

리스트 컴프리헨션 1차원

어려운 게 아니고, 리스트를 조건을 달고 초기화하는 방법이다. 리스트 대괄호 안에 조건문, 반복문을 넣어서 리스트를 초기화 할 수 있다. 자세한 것은 다음 글을 참고.

https://100won-developer.tistory.com/entry/list-comprehension-list%EB%A5%BC-%EC%BD%94%EB%93%9C-%ED%95%9C%EC%A4%84%EB%A1%9C-%EC%B4%88%EA%B8%B0%ED%99%94%ED%95%98%EA%B8%B0

 

list comprehension - list를 코드 한줄로 초기화하기

이 포스트에서는 list comprehension의 아주 간단한 형태만 보여주는데, 조금 더 숙달이 된다면 [ 출력되는 형태 또는 식 for 변수 in range(범위) if ~~] 처럼 한줄로 더 세세한 내용을 담을 수도 있다. 밑

100won-developer.tistory.com

 

만약 0부터 19까지 중에서 홀수만 리스트에 담고자 한다면 빈 리스트 선언하고, for문 쓰고 if 홀수면 리스트에 append ... 이 작업을 몇줄에 걸쳐서 해야할 것이다. 하지만 리스트 컴프리헨션으로 다음과 같이 한줄로 쓸 수 있다.

arr = [i for i in range(20) if i % 2 == 1]

 

리스트 컴프리헨션 2차원

2차원 리스트를 초기화하는 작업은 매우 매우 자주 나올 것이다. 꼭 알아두자.

row = 3
col = 4
lst = [ [0] * col for _ in range(n) ] # col개 짜리가 row개 반복됨

결과 : [ [0,0,0,0], [0,0,0,0], [0,0,0,0] ]

 

사실 2차원 리스트의 초기화는 반드시 이런 방법을 쓰는 게 좋아보인다. 그렇지 않으면 다음과 같은 실수가 나온다.

row = 3
col = 4

arr = [ [0]*col ]*row
결과 : [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]

arr[1][1] = 5
결과 : [[0, 5, 0, 0], [0, 5, 0, 0], [0, 5, 0, 0]]

1열의 모든 값들이 바뀌어버린다. 따라서 2차원 리스트를 초기화한다면 반드시 리스트 컴프리헨션을 이용해서 바꾸자.

 

for문 언더바

위 예시에서도 그렇고, 종종 for문에서 언더바를 보게 된다.

for _ in range(5):
	print("hi")

한마디로, 변수가 굳이 필요하지 않아서 단순히 출력만 할 때 언더바를 이용할 수 있다.

 

리스트 관련 메소드

메소드명 사용방법 설명 시간 복잡도
append() ★ x.append() 원소 하나 삽입 O(1)
sort() x.sort() 오름차순 정렬 O(N logN)
x.sort(reverse=True) 내림차순 정렬
reverse() x.reverse() 원소 순서를 거꾸로 뒤집는다. O(N)
insert() x.insert(삽입위치, 추가할 값) 특정 위치에 원소 삽입 O(N)
count() x.count(값) 특정 값을 가지는 데이터의 "개수" 반환 O(N)
remove() x.remove(지울 값) 특정 값을 가지는 원소를 제거. 단, 해당 원소가 여러개면 하나만 제거. O(N)

 

append  insert  remove

주의할 점은 insert, append, remove이다.

  • insert는 원소 삽입 후 뒤에 원소들의 위치를 재조정해야돼서 오래걸려 시간복잡도가 O(N)이다.
  • append는 단순히 맨 뒤에 추가해주는 것이기 때문에 O(1)이다. 즉, insert를 많이 쓰면 시간초과가 될 수 있으니, 둘 다 쓸 수 있는 상황이라면 append를 사용하자.
  • remove도 insert처럼 삭제 후 위치 재조정때문에 시간복잡도가 O(N)이다.

remove 강화 - remove all

remove 메소드의 설명을 보면, 원소가 여러개 있어도 1개만 제거한다고 되어있다. 즉, [1,2,2,3]에서 remove(2)를 해도 [1,2,3]처럼 2가 살아있다. 만약 우리가 2를 모두 지우고 싶다면 어떻게 될까? remove_all 같은 메소드가 있다면 참 좋겠지만 파이썬에서는 지원하지 않으므로 다음과 같이 여집합 개념을 이용한다. 우리가 지울 대상을 모아두고 여기에 없는 값들만 결과 list에 담아주겠다는 맥락이다.

arr = [1,2,2,3,4,4,5]
remove_set = {2, 4} # 2와 4를 지우고 싶다

result = [i for i in arr if i not in remove_set]
결과 : result = [1,3,5]