python์ ํตํด ํ ๋ฆฌ์คํธ๋ฅผ ๋ค๋ฅธ ๋ณ์์ ํ ๋นํ๋ ๊ฒฝ์ฐ๊ฐ ์์ฃผ ์๋ค. ๋ฆฌ์คํธ๋ฅผ ๋ณ์์ ํ ๋นํ๋ ๊ฒ์ด (์๋ก์ด ๋ณ์์)๋ณต์ฌ๋์๋ค๊ณ ์ฐฉ๊ฐํ ๋, ์์๊ณผ ๋ค๋ฅธ ๊ฒฐ๊ณผ๊ฐ ์ถ๋ ฅ๋ ๊ฒ์ด๋ค.
์๋ ์ผ์ด์ค๋ ์ฐฉ๊ฐํ๊ฒ ๋๋ ์๋๋ฆฌ์ค์ด๋ค.
list1 = [1, 2, 3, 4]
list2 = list1 # list1์ list2์ '๋ณต์ฌ'
# list2 ์์
list2[1] = 100
list2.append(5)
# list2 ์ถ๋ ฅ
print(list2) # [1, 100, 3, 4, 5]
# list1์ ๊ทธ๋๋ก๊ฒ ์ง?
print(list1) # [1, 100, 3, 4, 5] ๐ค
list2๋ฅผ ์์ (์กฐ์)ํ๋๋ฐ, list1์ด ๋์ผํ๊ฒ ๋ณ๊ฒฝ๋์๋ค. ์๋ํ ๊ฒ์ด ์๋ ๊ฒ์ด๋ค. ์ด๋ ๊ฒ ์๋ ๋๋ ์ด์ ์ ๋ํด ์์๋ณธ๋ค.
python์์ list์ ๊ฐ์ 'mutable(๊ฐ๋ณ)' ๊ฐ์ฒด๋ฅผ ๋ค๋ฃฐ ๋, ๋จ์ ํ ๋น ์ฐ์ฐ('=')์ ์ฌ์ฉํ๋ฉด ์๋ณธ ๊ฐ์ฒด์ ๋ํ ์ฐธ์กฐ๋ง์ ์์ฑํ๋ค. ์๋ณธ ๊ฐ์ฒด์ ๋ํ ์ฐธ์กฐ๋ผ๊ณ ํ๋ฉด, ์ ์ฝ๋์์ [1, 2, 3, 4] ๋ผ๋ ๋ฆฌ์คํธ๊ฐ ๋ด๊ฒจ ์๋ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ฅผ ํ ๋นํ๋ ๊ฒ์ด๋ค. ์ฆ, list1์ด [1, ..., 4] ๋ฆฌ์คํธ๋ฅผ ๋ด๊ณ ์๋ ์์น ์ ๋ณด(๋ฉ๋ชจ๋ฆฌ ์ฃผ์)๋ฅผ list2์๊ฒ ์ฃผ๋ ๊ฒ(!).
'mutable'ํ ๊ฐ์ฒด(list, dict, ndarray(NumPy์ ๋ฐฐ์ด))๋ฅผ ํ ๋น ์ฐ์ฐํ ๋ ์ด๋ฅผ ์์งํ๊ณ ์ฌ์ฉํ๋๋ก ํ์! list1๋ list2๋ ๊ฐ์ ์ฃผ์๋ฅผ ์ฐธ์กฐํ๊ธฐ์ ์ถ๊ฐ์ ์ธ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ง ์๋๋ค. ๋ง์ฝ, ์ฐธ์กฐํ๋ ์ฃผ์๊ฐ ์๋[1, ..., 4]์ ๊ฐ์ ๋ฆฌ์คํธ ์์ฒด๋ฅผ ๋ณต์ฌํ๊ณ ์ถ์ ๊ฒฝ์ฐ ์ด๋ป๊ฒ ํ ์ ์์๊น? 'shallow copy'์ 'deep copy'๋ฅผ ์์๋ณด์.
1. Shallow Copy
๊ฐ์ฒด์ ์ฒซ ๋ฒ์งธ ๋ ๋ฒจ๋ง ๋ณต์ฌํ๋ ๊ฒ์ ์๋ฏธํ๋ค. ์ฒซ ๋ฒ์งธ ๋ ๋ฒจ์ด๋ผ๊ณ ํ๋ฉด, [1, ..., 4]์ธ ๋ฆฌ์คํธ์์ ๊ฐ์ฅ ๋ฐ๊นฅ์ '๊ป๋ฐ๊ธฐ'๋ผ๊ณ ์๊ฐํ ์ ์๋ค. ์ฆ, ๋ฆฌ์คํธ์ ์ต์์ ๋ ๋ฒจ๋ง ๋ณต์ ๋๊ณ , ๋ฆฌ์คํธ ๋ด๋ถ์ ๋ ๋ค๋ฅธ mutable ๊ฐ์ฒด๊ฐ ์๋ค๋ฉด ์ด๋ '์ฐธ์กฐ ์ฃผ์'๋ฅผ ๋ณต์ฌํ๋ ๊ฒ.
'๊ป๋ฐ๊ธฐ'๋ ๊ฐ์ฒด๊ฐ ์์ ํ ๋ถ๋ฆฌ๊ฐ ๋์๋ค. ๋ค๋ง, '๊ป๋ฐ๊ธฐ' ์์ ์๋ mutable ๊ฐ์ฒด๋ ์ฌ์ ํ ๋์์ ๊ฐ์ ์ฃผ์๋ฅผ ์ฐธ์กฐ ์ค์ด๋ค. ์ด ๊ฒฝ์ฐ list2 ๋ด๋ถ์ ์ค์ฒฉ๋ [1, 2, 3]์ ์์ (์กฐ์)ํ ๊ฒฝ์ฐ list1 ๋ด๋ถ์๋ ๋์ผํ๊ฒ ์ ์ฉ๋๋ค. ์ต์์ ๊ฐ์ฒด์ ๋ณต์ฌ๋ณธ์ ๋ง๋ค ๋ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ถ๊ฐ๋ก ์ฌ์ฉํ๊ธฐ์ ํ ๋น ์ฐ์ฐ๋ณด๋ค ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ด ๋ง๋ค. '๊ป๋ฐ๊ธฐ' ์์ ์๋ ๊ฒ๋ ์์ ํ ์๋กญ๊ฒ ๋ณต์ ํ ๋๋ 'Deep copy'๋ฅผ ์ฌ์ฉํ๋ค.
2. Deep copy
์ค์ฒฉ๋ list, dictionary ํ๋ ์์ ํ ๋ ๋ฆฝ์ ์ผ๋ก ๋ณต์ ํ ์ ์๋ค. ์ด ๊ฒฝ์ฐ shallow copy์์ ๊ฐ์ ์ฃผ์๋ฅผ ์ฐธ์กฐํ๋ ๋ด๋ถ list๋ ์์ ํ ์๋ก์ด ์ฃผ์๋ฅผ ๊ฐ๋ฆฌํค๊ฒ ๋๋ค. ์๋ณธ ๊ฐ์ฒด, ์ค์ฒฉ๋ ๊ฐ์ฒด ๋ชจ๋์ ๋ํ ๋ณต์ฌ๋ณธ์ ๋ง๋ค๊ธฐ์ shallow copy๋ณด๋ค ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ด ํฌ๋ค. ๋ณต์ฌ๋ณธ์ด๋ ์๋ณธ์ด๋ ์์ ํด๋ ๊ฐ ๊ฐ์ฒด์ ์๋ฌด๋ฐ ์ํฅ์ ์ฃผ์ง ์๋๋ค.
3. ์์ ์ฝ๋
import copy
original_list = [[1, 2, 3], [4, 5, 6]]
# ํ ๋น ์ฐ์ฐ
assigned_list = original_list
# Shallow Copy
shallow_copied_list = original_list.copy()
# Deep Copy
deep_copied_list = copy.deepcopy(original_list)
# ์๋ณธ ๊ฐ์ฒด ์กฐ์
original_list[0][0] = 100
print("Original:", original_list)
print("Assigned:", assigned_list)
print("Shallow Copied:", shallow_copied_list)
print("Deep Copied:", deep_copied_list)
# ์ถ๋ ฅ ๊ฒฐ๊ณผ
# Original: [[100, 2, 3], [4, 5, 6]]
# Assigned: [[100, 2, 3], [4, 5, 6]]
# Shallow Copied: [[100, 2, 3], [4, 5, 6]]
# Deep Copied: [[1, 2, 3], [4, 5, 6]]
์๋ณธ ๊ฐ์ฒด์ ์ค์ฒฉ๋ ๋ฆฌ์คํธ๋ฅผ ์กฐ์ํ์ 'shallow copy'ํ ๊ฐ์ฒด์ ๊ฒฝ์ฐ ํจ๊ป ์กฐ์๋๋ ๊ฒ์ ํ์ธํ ์ ์๋ค. ๋ฐ๋ฉด์ 'deep copy'ํ ๊ฐ์ฒด์ ๊ฒฝ์ฐ ๋ ๋ฆฝ์ ์ด๋ค. Shallow copy๋ฅผ ํตํด '๊ป๋ฐ๊ธฐ'๋ ์๋กญ๊ฒ ํ ๋นํ์ง๋ง, ๋ด๋ถ ๋ฆฌ์คํธ์ ์ฐธ์กฐ ์ฃผ์๋ ์๋ณธ ๊ฐ์ฒด์ ๋์ผํจ์ ํ์ธํ ์ ์๋ค.