반응형
최근 파이썬으로 순열을 짜다가 놓치고 있는 게 있는 것 같아 글을 쓴다.
다음과 같이 1번 코드, 2번 코드는 순열(permutation)을 재귀 함수로 푸는 코드이다. 차이점은 5번째 줄 arr.append()에 파라미터로 tmp를 주느냐, tmp[:]를 주느냐의 차이다.
## 1번 코드
def permute(self, nums: List[int]) -> List[List[int]]:
arr = []
def backtrack(tmp = []):
if len(tmp) == len(nums):
arr.append(tmp)
return
for n in nums:
if n in tmp:
pass
else:
tmp.append(n)
backtrack(tmp)
tmp.pop()
return
backtrack()
return arr
## 2번 코드
def permute(self, nums: List[int]) -> List[List[int]]:
arr = []
def backtrack(tmp = []):
if len(tmp) == len(nums):
arr.append(tmp[:]) #1번 코드와 다른점
return
for n in nums:
if n in tmp:
pass
else:
tmp.append(n)
backtrack(tmp)
tmp.pop()
return
backtrack()
return arr
하지만 각 코드의 결과는 다르다.
#1번코드 결과
permute([1,2,3]) # [[],[],[],[],[],[]]
#2번코드 결과
permute([1,2,3]) # [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
그이유는 arr 안에 들어가는 tmp는 유동적이지만 tmp의 주소는 바뀌지 않기 때문이다. tmp[:]은 주소는 제외하고 copy 할 수 있다. 따라서 1번 코드와 2번 코드의 6번째 줄에 print(arr)을 추가해보면 재밌는 결과가 나온다.
#1번코드
def combine(self, n: int, k: int) -> List[List[int]]:
arr = []
def backtrack(tmp = [], start=1):
if len(tmp) == k:
arr.append(tmp)
print(arr)
return
for i in range(start, n+1)
tmp.append(i)
backtrack(tmp, i+1)
tmp.pop()
return
backtrack()
return arr
combine([1,2,3])
#[[1, 2]]
#[[1, 3], [1, 3]]
#[[1, 4], [1, 4], [1, 4]]
#[[2, 3], [2, 3], [2, 3], [2, 3]]
#[[2, 4], [2, 4], [2, 4], [2, 4], [2, 4]]
#[[3, 4], [3, 4], [3, 4], [3, 4], [3, 4], [3, 4]]
#2번코드
def combine(self, n: int, k: int) -> List[List[int]]:
arr = []
def backtrack(tmp = [], start=1):
if len(tmp) == k:
arr.append(tmp[:])
print(arr)
return
for i in range(start, n+1)
tmp.append(i)
backtrack(tmp, i+1)
tmp.pop()
return
backtrack()
return arr
combine([1,2,3])
#[[1, 2]]
#[[1, 2], [1, 3]]
#[[1, 2], [1, 3], [1, 4]]
#[[1, 2], [1, 3], [1, 4], [2, 3]]
#[[1, 2], [1, 3], [1, 4], [2, 3], [2, 4]]
#[[1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4]]
위와 같이 1번 코드는 tmp의 값이 재귀를 돌면서 계속 변하는데, 변한 마지막 값으로 같은 주소를 공유하는 tmp들이 다 변한다.
파이썬으로 코딩하다보면 가끔 포인터, 주소에 대해 무신경해질 때가 가끔 있는 듯하다. 놓치지 말고 잘 챙기자.
728x90
반응형
'python > 파이썬 코딩의 기술' 카테고리의 다른 글
Thread - 파이썬 코딩의 기술 리뷰[동시성과 병렬성 2] (0) | 2022.03.01 |
---|---|
python3 애트리뷰트, 메타클래스 - 2 (0) | 2022.02.20 |
파이썬 코딩의 기술 리뷰 - 메타클래스와 애트리뷰트 1 (0) | 2022.02.01 |
파이썬 코딩의 기술 리뷰 - 클래스, 인터페이스 (0) | 2022.01.16 |
파이썬 코딩의 기술 리뷰- 동시성과 병렬성 1 (2) | 2022.01.10 |