python

[python] list - 2중, 3중 리스트 생성

KyuminKim 2024. 1. 2. 18:52

일단 2중, 3중 리스트 생성 시 기억해야 할 점은

 

1. 리스트는 for _ in range() 구문과 * 구문의 적절한 조합으로 생성 가능하다는 것,

   - * 사용 시 자동으로 1회 unpacking이 이루어 진다는 것

   - for _ in range() 사용 시 자동 unpacking은 없으나, 타입이 generator 객체이므로 list로 형변환 할 것

2. for _ in range() 구문에서 순서 주의할 것 (column -> row 순서

이 두 가지이다.

 

 

경우에 따라 나눠, 자세히 알아보자.

 


1.  2중 리스트 생성


[1] 목표 설정

예를 들어 다음과 같은  row = 3, column = 2인 2중 리스트를 생성한다고 가정하자.

즉,  [[0, 0], [0, 0], [0, 0]]인 리스트를 생성하자.

[[0, 0], [0, 0], [0, 0]] 2중 리스트

 

 


[2] 코드 작성

# 목표
# [[0, 0], [1, 1], [2, 2]]

해당 목표를 달성하기 위한 코드는 여러 가지가 있다.

 

 

(1) * 구문 (O)

# (1)
print([[0] * 2] * 3)
# 결과: [[0, 0], [0, 0], [0, 0]]

- [0, 0] : 가장 안쪽의 리스트를 (column 수만큼을 크기=원소개수=len 로 갖는)  생성하고 ([0] * 2 결과)

- [0, 0], [0, 0], [0, 0] : *3을 함으로써 row를 생성한다 ([[0, 0]] * 3 결과)

 ** 주의: [[0, 0]] * 3 이 아니라, [0, 0] * 3 사용 시 [0, 0, 0, 0, 0, 0] 출력 

** 즉, * 사용 시에는 한 번 더 []로 감싸야 함

 

 

(2) * 구문과 for _ in range() 구문 (O)

# (2)
print([[0] * 2 for _ in range(3)])
# 결과: [[0, 0], [0, 0], [0, 0]]

# 참고: type([0] * 2 for _ in range(3)) -> <class 'generator'>

- [0, 0]: 가장 안쪽의 리스트를 (column 수만큼을 크기=원소개수=len 로 갖는)  생성하고([0] * 2 결과)

- [0, 0], [0, 0], [0, 0] : for _ in range(3) 문을 통해  [0] * 2를 3번 반복한다는 의미이다. 

      이때, for _ in range(3)문의 return값은 generator이다.

      원소를 확인하면 [0, 0]이 각 원소인 것을 확인할 수 있다.

generator = ([0] * 2 for _ in range(3))
for item in generator:
    print(item)
# 결과: [[0, 0], [0, 0], [0, 0]]

       for _ in range(3) 구문의 결과 (generator)를 리스트로 변환하여 -> 원하는 배열 [[0, 0], [0, 0], [0, 0]]을 얻을 수 있다.

      ([for구문] 을 통해 리스트로 변환)

 

 

(3) * 구문과 for _ in range() 구문 (X)

# (3)
print([[0] for _ in range(2)] * 3)
# 결과: [[0], [0], [0], [0], [0], [0]]

 

(2) 경우와 for문, *의 순서만 바뀌었다.

이때 [0]이 하나씩만 만들어진다.

- generator 객체: [0] for _ in range(2)의 결과

- [[0], [0]] : [[0] for _ in range(2)]의 결과

- [0], [0] : [[0], [0]]을 1번 언패킹한 결과 ([[0], [0]] * 3의 중간과정)

- [[0], [0], [0], [0], [0], [0]]: [[0], [0]] * 3의 결과

 


[3] 결론

[0] -> [0, 0]으로 만들기 위해서는 *를 이용해야 한다. (for문 사용 안됨 !)

[0] -> [0], [0]으로 만들기 위해서는 * 또는 for _ in range() 구문을 이용한다. 

    - * 사용 시, 한 번 더 []로 감싸야 한다  (unpacking 자동으로 1번 이루어짐)

    - for _ in range() 사용 시, unpacking이 자동으로 이루어지지 않는다. (단, 결과가 generator 객체이므로 list 형변환 필요)

 

 

 

 


2.  3중 리스트 생성


[1] 목표 설정

예를 들어 다음과 같은  높이=2, 세로=2, 가로=3인 2중 리스트를 생성한다고 가정하자.

즉,  [ [[0, 0, 0], [0, 0, 0]],  [[0, 0, 0], [0, 0, 0]] ] 인 리스트를 생성하자.

[ [[0, 0, 0], [0, 0, 0]],&nbsp;&nbsp;[[0, 0, 0], [0, 0, 0]] ] &nbsp;3중 리스트

 


[2] 코드 작성

# 목표
# [[[0, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 0]]]

해당 목표를 달성하기 위한 코드는 여러 가지가 있다.

 

 

# (1)
print([[[0] * 3 for _ in range(2)] for _ in range(2)])
# 결과: [[[0, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 0]]]

- [0, 0, 0] : [0] * 3의 결과

- [[0, 0, 0], [0, 0, 0], [0, 0, 0]] :  [[0] * 3 for _ in range(2)]의 결과

- [[[0, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 0]]]:  [[0] * 3 for _ in range(2)] for _ in range(2)의 결과

** 즉, * 사용 시에는 한 번 더 []로 감싸야 함

 

# (1) 
print([[[0] *3 for _ in range(2)] for _ in range(2)])
# 결과: [[[0, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 0]]]

# (2)
print([[[0] *3] * 2 for _ in range(2)])
# 결과: [[[0, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 0]]]

# (3)
print([[[0] *3] * 2] * 2)
# 결과: [[[0, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 0]]]

 

아래 모두 다 가능 !

 

- [[[[0] * 가로] for _ in range(세로)] * 높이 

- [[[[0] * 가로] for _ in range(세로)] for _ in range(높이)]           # (1) 

- [[[[0] * 가로] * 세로 for _ in range(높이)]                                 # (2) 

- [[[[0] * 가로] * 세로] * 높이                                                       # (3)


[3] 결론 (2중 리스트 결론과 동일)

[0] -> [0, 0]으로 만들기 위해서는 *를 이용해야 한다. (for문 사용 안됨 !)

[0] -> [0], [0]으로 만들기 위해서는 * 또는 for _ in range() 구문을 이용한다. 

    - * 사용 시, 한 번 더 []로 감싸야 한다  (unpacking 자동으로 1번 이루어짐)

    - for _ in range() 사용 시, unpacking이 자동으로 이루어지지 않는다. (단, 결과가 generator 객체이므로 list 형변환 필요)