개념

[파이썬 자료구조] 1. 배열 (Array) array — 효율적인 숫자 배열 — Python 3.14.2 문서 매트릭스 구조, built-in 자료형으로도 존재. 여기서는 2차원 리스트로 사용자가 구현하는 방식 위주로 서술

- 차원별 리스트 만들기

  1. 0차원 리스트 [0 * 10] (괄호 안에서 곱하기) 계산: 결과: [0]

  2. 1차원 리스트[0] * 10 (괄호 밖에서 곱하기) 계산: [0] + [0] + … (10번 반복) 결과: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] 파이썬의 * 연산자는 “대괄호 안에 있는 내용물”만 복사, 이어 붙인다.

  3. 2차원 리스트[[0] * 5 for _ in range(3)] (리스트 컴프리헨션(List Comprehension)) 1차원 리스트를 for 문 돌려서 여러 번 반복, 예시의 경우 0이 5개 든 개별 리스트 3개 생겨서 묶여있음

중요한 2차원 리스트 input 받기 Input()

주의! 2차원 리스트의 경우 얕은 복사(Shallow Copy) List 문서의 “복사”부분 참고 ex)[[0, 0, 0, 0, 0]] * 3 내부에서 같은 리스트 공유 중 개별 리스트 1개 뿐

# 1. 곱하기로 2차원 리스트 생성
matrix = [[0]] * 3 
# matrix = [[0], [0], [0]]
 
# 2. 나는 "첫 번째 리스트"의 값만 100으로 바꾸고 싶음
matrix[0][0] = 100 
 
# 3. 결과 확인
print(matrix)
# 기대: [[100], [0], [0]]
# 실제: [[100], [100], [100]]  <-- 으악!!! 다 바뀜!!!
해결

각 행이 서로 독립적인 리스트가 되도록 하기 위해서는, 반복문을 통해 새로운 리스트를 하나씩 생성하여 추가해야 합니다. [[]]*5 이런 것도 얕은 복사. 행이 한 줄인 이중 리스트 만들려면 [[] for _ in range (5)] 이런 식으로 반복문을 무조건 써야 함

n, m = 3, 4
grid = []
 
for _ in range(n):
    grid.append([0] * m)
 
// 또는 grid = [[0]*m for _ in range(n)] 으로 가능합니다.
 
`grid[0][1] = 7 print(grid) 
// 출력 결과 [[0, 7, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]`

이 방식은 반복문이 실행될 때마다 [0] * m이라는 새로운 리스트를 생성하여 grid에 추가하기 때문에, 각 행이 서로 다른 리스트가 되어 해결

- 전치 행렬 (Transpose matrix)

행과 열 뒤바뀐 90도 회전 느낌, 행과 열 인덱스 같은 좌표들 기준으로 뒤집힘 일단 이중 for문으로 싹 돌면서 대각선 반 틈만 서로 대입해서 바꾸기 (i가 j보다 작거나 큰 경우)

#**** 
##***
 
###**
####*
##### 
이런 느낌으로 대각선 반 틈만 적용 -> 아래의 "if i<j:" 코드가 있는 이유
모든 좌표에 뒤집기 적용하면 2번 뒤집혀서 원상복구 됨
 
arr = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] #n, m 모두 3
 
for i in range (3): #n
	for j in range (3): #m
		if i<j:
			arr[i][j], arr[j][i] = arr[j][i], arr[i][j] #대각선 아래 위 각각을 바꿔줌

Zip()함수 써서 손쉽게 만들 수 있음 Zip()

2. row.count() 활용 (추천)

리스트에는 특정 원소의 개수를 세주는 .count()라는 내장 함수가 있습니다. 이를 각 행(row)마다 적용하면 훨씬 간결해집니다.

Python

count = sum(row.count(1) for row in arr)
  • 해석: row.count(1)은 각 줄에 있는 1의 개수를 반환합니다.

  • 제너레이터 사용: 아까 배운 제너레이터 표현식으로 각 행의 1의 개수들을 하나씩 뽑아 sum()으로 모두 더한 것입니다.

3. 리스트를 1차원으로 풀어서 세기 (Flatten)

2차원을 1차원으로 쫙 펼친 다음 세는 방법입니다.

Python

# 2차원 리스트를 1차원으로 병합
flat_list = sum(arr, []) 
count = flat_list.count(1)

참고: sum(arr, [])는 2차원 리스트를 1차원으로 합치는 트릭 중 하나입니다. 데이터 양이 아주 많지 않을 때 유용합니다.

1. 가장 깔끔한 방법: sum()과 리스트 컴프리헨션

파이썬의 내장 함수인 count()를 각 행(row)에 적용하는 방식입니다. 가독성이 가장 좋고 일반적인 상황에서 가장 많이 쓰입니다.

Python

matrix = [[1, 0, 1], [0, 1, 1], [1, 1, 0]]

# 각 행에서 1의 개수를 세어 모두 더함
count = sum(row.count(1) for row in matrix)
print(count)  # 결과: 6

sum(sum(arr,[])) 성능 문제: “거북이급” 속도 (O(N2))

sum(arr, [])는 내부적으로 리스트를 하나씩 합칠 때마다 새로운 리스트를 계속 생성합니다.

  • 첫 번째 행과 두 번째 행을 더해 새 리스트 생성

  • 그 결과와 세 번째 행을 더해 또 새 리스트 생성…

이 과정에서 데이터를 계속 복사하기 때문에, 리스트가 커질수록 속도가 기하급수적으로 느려집니다. 파이썬 공식 문서에서도 이 방식으로 리스트를 펼치는 것은 성능상 좋지 않다고 명시하고 있습니다.

2. 논리적 오류: “합계”와 “개수”의 차이

sum()은 말 그대로 안에 있는 숫자들을 모두 더하는 함수입니다.

  • 만약 리스트에 1만 있다면 개수를 세는 것과 결과가 같겠지만,

  • 리스트에 [[2, 0], [1, 1]]처럼 2 같은 다른 숫자가 섞여 있다면?

    • sum(sum(arr, [])) 결과는 4가 나오지만,

    • 실제 1의 개수는 2개입니다.

즉, 리스트에 0과 1만 들어있는 게 보장될 때만 ‘개수’처럼 동작합니다.