<jupyter_start><jupyter_text>Shallow vs Deep Copying<jupyter_code>org = 5
cpy = org # this won't make a real copy it will only create a new variable with the same reference
cpy = 6
print(cpy)
print(org)
org = [0, 1, 2, 3, 4]
cpy = org # this assignment doesn't make actual copy
cpy[0] = -10
print(cpy)
print(org)
import copy<jupyter_output><empty_output><jupyter_text>- shallow copy: one level deep, only references of nested child objects - deep copy: full independent copy  Shallow copy<jupyter_code>org = [0, 1, 2, 3, 4]
cpy = copy.copy(org)
cpy[0] = -10
print(cpy)
print(org)
# shallow copy in lists
org = [0, 1, 2, 3, 4]
cpy = org.copy()
cpy[0] = -10
print(cpy)
print(org)
# shallow copy in lists
org = [0, 1, 2, 3, 4]
cpy = list(org)
cpy[0] = -10
print(cpy)
print(org)
# shallow copy in lists
org = [0, 1, 2, 3, 4]
cpy = org[:]
cpy[0] = -10
print(cpy)
print(org)
org = [[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]]
cpy = copy.copy(org)
cpy[0][1] = -10
print(cpy)
print(org)
# now shallow copy won't work becasue shallow copy is only one level deep<jupyter_output>[[0, -10, 2, 3, 4], [5, 6, 7, 8, 9]]
[[0, -10, 2, 3, 4], [5, 6, 7, 8, 9]]<jupyter_text>Deepcopy<jupyter_code># we have to use deep copy
org = [[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]]
cpy = copy.deepcopy(org)
cpy[0][1] = -10
print(cpy)
print(org)<jupyter_output>[[0, -10, 2, 3, 4], [5, 6, 7, 8, 9]]
[[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]]<jupyter_text>Copying custom objects<jupyter_code>class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

p1 = Person('Szymon', 20)
p2 = p1

p2.age = 28
print(p2.age)
print(p1.age)
# both got affected because this is not an actual copy
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

p1 = Person('Szymon', 20)
p2 = copy.copy(p1)

p2.age = 28
print(p2.age)
print(p1.age)
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

class Company:
    def __init__(self, boss, employee):
        self.boss = boss
        self.employee = employee
        
p1 = Person('Alex', 55)
p2 = Person('Joe', 28)

company = Company(p1, p2)
company_clone = copy.copy(company)

company_clone.boss.age = 56
print(company_clone.boss.age)
print(company.boss.age)
# it got affected becasue we used shallow copy and the age is at the level 2
# we have to use deepcopy
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

class Company:
    def __init__(self, boss, employee):
        self.boss = boss
        self.employee = employee
        
p1 = Person('Alex', 55)
p2 = Person('Joe', 28)

company = Company(p1, p2)
company_clone = copy.deepcopy(company)

company_clone.boss.age = 56
print(company_clone.boss.age)
print(company.boss.age)<jupyter_output>56
55
{'fraction_non_alphanumeric': 0.15087593850554165, 'fraction_numerical': 0.05648909545942081, 'mean_word_length': 3.5348460291734196, 'pattern_counts': {'":': 0, '<': 14, '<?xml version=': 0, '>': 14, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '4', 'dir': 'jupyter-structured-clean-dedup', 'id': '30954', 'license': 'MIT', 'n_tokens_mistral': 1215, 'n_tokens_neox': 1104, 'n_words': 357, 'path': '20_Shallow vs Deep Copying.ipynb', 'repo_name': 'Szymon-Budziak/Intermediate-Python', 'size': '2797'}