wecode의 codekata week5-day1을 풀다가 해당 궁금증이 생겼다.
week5-day1 코드카타의 문제는 아래와 같다.
정렬을 해야하는 배열은 [7,5,4,2] 입니다.
첫 번째 loop에서는 index 0부터 3까지 확인하며 가장 작은 수를 찾습니다.
2 이므로 index 0의 7과 교체합니다. -> [2,5,4,7]
두 번째는 index 1부터 3까지 확인하며 가장 작은 수를 찾습니다.
4이므로 index 1의 5와 교체합니다 -> [2,4,5,7]
세 번째는 index 2부터 3까지.. 이런식으로 가장 작은 수를 선택해서 순서대로 교체하는 것을 선택정렬이라고 합니다.
# Problem Statement
nums라는 정렬되지 않은 숫자 배열을 주면, 오름차순(1,2,3..10) 으로 정렬된 배열을 return해주세요.
선택정렬 알고리즘으로 구현하셔야겠죠??
def selectionSort(nums):
for i in range(len(nums) - 1):
min_num = min(nums[i + 1:len(nums)])
if min_num < nums[i]:
nums[nums.index(min_num)], nums[i] = nums[i], nums[nums.index(min_num)]
return nums
위의 답안은 성공적으로 nums=[64, 25, 12, 22, 11]
를 [11, 12, 22, 25, 64]
로 바꾸어준다.
하지만 위의 코드에서 nums[nums.index(min_num)], nums[i] = nums[i], nums[nums.index(min_num)]
부분을 자리만 바꾸어서
nums[i], nums[nums.index(min_num)] = nums[nums.index(min_num)], nums[i]
로 실행하면 자리가 하나도 바뀌지 않고 [64, 25, 12, 22, 11]
을 그대로 반환한다.
왜 그런 것일까??
nums = [0, 1, 2, 3, 4]
# 1번
nums[nums.index(4)], nums[2] = nums[2], nums[nums.index(4)]
# 2번
nums[2], nums[nums.index(4)] = nums[nums.index(4)], nums[2]
1번의 진행상황을 뜯어보자.
nums[2]
와 nums[nums.index(4)]
의 값을 저장해둔다.nums[2] = 2
이고,nums[nums.index(4)] = nums[4] = 4
이다.nums[nums.index(4)] = 2
대입을 진행한다.nums[nums.index(4)] = nums[4] = 2
이므로, nums[0, 1, 2, 3, 4]
에서 [0, 1, 2, 3, 2]
가 된다.nums[2] = 4
대입을 진행한다.nums[2] = 4
로 인해, nums는 [0, 1, 2, 3, 2]
에서 [0, 1, 4, 3, 2]
로 변경된다.결과적으로 우리가 원했던 결과(4번 인덱스와 2번 인덱스의 swapt)가 나온다.
이번엔 2번의 진행상황을 뜯어보자.
nums[nums.index(4)]
와 nums[2]
의 값을 저장해둔다.nums[nums.index(4)] = nums[4] = 4
이고, nums[2] = 2
이다.nums[2] = 4
대입을 진행한다.nums[2] = 4
로 인해, nums는 [0, 1, 2, 3, 4]
에서 [0, 1, 4, 3, 4]
로 변경된다.nums[nums.index(4)] = 2
대입을 진행한다.nums=[0, 1, 4, 3, 4]
이므로 nums[nums.index(4)]
는 nums[4]
가 아닌 nums[2]
가 된다.nums[2] = 2
대입을 적용하면, nums[0, 1, 4, 3, 4]
에서 [0, 1, 2, 3, 4]
가 된다.결과적으로 우리가 원했던 결과(4번 인덱스와 2번 인덱스의 swapt)가 아닌, 처음의 nums
가 그대로 반환된다.
list의 index swap을 위해 우리는 a, b = c, d
형태를 사용하게 된다.
이 때, c
와 d
의 값을 저장한 후, 저장한 c
의 값을 a
에 대입하고, 그 후에 저장한 d
의 값을 b
에 저장한다.
그러므로, nums[nums.index(4)]
혹은 nums[nums[2]]
와 같이 index 자리에서 다른 index를 불러오는 코드는 a
와 b
중 a
자리에 위치하는 것이 좋다.
왜냐하면 다른 index를 불러오는 코드가, 대입으로 인해 영향을 받기 전에 진행되어야 오류가 없기 때문이다.