Python'da Nusxalash

Python'da nusxalashning turli usullari, muhimligi va eng yaxshi amaliyotlarini o'rganing.

So'nggi yangilanish: 2024-12-20

Python'da nusxalash (copying) obyektlarning nusxalarini yaratish jarayonidir. Bu mavzu muhim, chunki u ma'lumotlar tuzilmalarini boshqarish, xotiradan samarali foydalanish va kutilmagan xatti-harakatlarning oldini olish uchun juda muhimdir. Ushbu qo'llanma Python'da nusxalashning turli jihatlari, usullari va eng yaxshi amaliyotlarini qamrab oladi.

Python'da asosan ikki xil nusxalash mavjud:

  1. Sayoz nusxalash (Shallow copy)
  2. Chuqur nusxalash (Deep copy)

Sayoz Nusxalash (Shallow Copy)

Sayoz nusxalash yangi obyekt yaratadi, lekin uning elementlariga referenslarni nusxalaydi.

import copy

original_list = [1, [2, 3], 4]
shallow_copy = copy.copy(original_list)

# O'zgarishlar
shallow_copy[0] = 5
shallow_copy[1][0] = 6

print("Original:", original_list)    # [1, [6, 3], 4]
print("Shallow copy:", shallow_copy) # [5, [6, 3], 4]

Chuqur Nusxalash (Deep Copy)

Chuqur nusxalash yangi obyekt yaratadi va rekursiv ravishda barcha ichki obyektlarni nusxalaydi.

import copy

original_list = [1, [2, 3], 4]
deep_copy = copy.deepcopy(original_list)

# O'zgarishlar
deep_copy[0] = 5
deep_copy[1][0] = 6

print("Original:", original_list)  # [1, [2, 3], 4]
print("Deep copy:", deep_copy)     # [5, [6, 3], 4]

Nusxalash Usullari

Python'da nusxalashning bir necha usullari mavjud:

  1. Tayinlash operatori (=)
  2. Ro'yxat/to'plam/lug'at yaratish usullari
  3. copy moduli
  4. Obyekt nusxalash metodlari

1. Tayinlash Operatori

original = [1, 2, 3]
copy = original  # Bu yangi obyekt yaratmaydi, faqat referensni nusxalaydi

2. Ro'yxat/To'plam/Lug'at Yaratish Usullari

# Ro'yxat
original_list = [1, 2, 3]
list_copy = original_list[:]  # Sayoz nusxa

# To'plam
original_set = {1, 2, 3}
set_copy = set(original_set)  # Sayoz nusxa

# Lug'at
original_dict = {'a': 1, 'b': 2}
dict_copy = dict(original_dict)  # Sayoz nusxa

3. copy Moduli

import copy

original = [1, [2, 3], 4]
shallow_copy = copy.copy(original)
deep_copy = copy.deepcopy(original)

4. Obyekt Nusxalash Metodlari

original_list = [1, 2, 3]
list_copy = original_list.copy()  # Sayoz nusxa

original_dict = {'a': 1, 'b': 2}
dict_copy = original_dict.copy()  # Sayoz nusxa

O'zgarmas (Immutable) va O'zgaruvchan (Mutable) Obyektlarni Nusxalash

O'zgarmas obyektlar (masalan, sonlar, satrlar, kortejlar) nusxalanganda, yangi obyekt yaratilmaydi:

a = 5
b = a
b += 1
print(a, b)  # 5 6

O'zgaruvchan obyektlar (masalan, ro'yxatlar, lug'atlar, to'plamlar) nusxalanganda, referens nusxalanadi:

a = [1, 2, 3]
b = a
b.append(4)
print(a, b)  # [1, 2, 3, 4] [1, 2, 3, 4]

Nusxalash bilan Bog'liq Muammolar

  1. Sayoz va chuqur nusxalash o'rtasidagi farqni tushunmaslik:
import copy

original = [[1, 2], [3, 4]]
shallow = copy.copy(original)
deep = copy.deepcopy(original)

original[0][0] = 5

print(original)  # [[5, 2], [3, 4]]
print(shallow)   # [[5, 2], [3, 4]]
print(deep)      # [[1, 2], [3, 4]]
  1. Murakkab obyektlarni nusxalash:
class ComplexObject:
    def __init__(self, value):
        self.value = value

obj1 = ComplexObject(5)
obj2 = copy.copy(obj1)  # Sayoz nusxa

obj2.value = 10
print(obj1.value, obj2.value)  # 5 10

Nusxalashda Ishlash Samaradorligi

Nusxalash usullarining ishlash samaradorligi:

import timeit
import copy

def test_assignment():
    original = [1, 2, 3]
    copy = original

def test_slice():
    original = [1, 2, 3]
    copy = original[:]

def test_copy_module():
    original = [1, 2, 3]
    copy = copy.copy(original)

def test_list_copy():
    original = [1, 2, 3]
    copy = list(original)

print("Assignment:", timeit.timeit(test_assignment, number=1000000))
print("Slice:", timeit.timeit(test_slice, number=1000000))
print("Copy module:", timeit.timeit(test_copy_module, number=1000000))
print("List copy:", timeit.timeit(test_list_copy, number=1000000))

Maxsus Nusxalash Metodlari

Ba'zi hollarda, o'zingizning nusxalash metodlaringizni yaratishingiz kerak bo'lishi mumkin:

class CustomObject:
    def __init__(self, value):
        self.value = value
    
    def __copy__(self):
        return CustomObject(self.value)
    
    def __deepcopy__(self, memo):
        return CustomObject(copy.deepcopy(self.value, memo))

obj = CustomObject([1, 2, 3])
obj_copy = copy.copy(obj)
obj_deepcopy = copy.deepcopy(obj)

Eng Yaxshi Amaliyotlar

  1. Nusxalash turini (sayoz yoki chuqur) aniq belgilang.
  2. Imkon qadar standart kutubxona funksiyalaridan foydalaning.
  3. Katta ma'lumotlar to'plamlarini nusxalashda ehtiyot bo'ling.
  4. Murakkab obyektlar uchun maxsus nusxalash metodlarini yarating.
  5. Nusxalash jarayonini test qiling, ayniqsa murakkab ma'lumotlar tuzilmalari uchun.

Tez-tez Uchraydigan Savollar

  1. Savol: Qachon sayoz nusxalash, qachon chuqur nusxalash ishlatish kerak? Javob: Agar faqat yuqori darajadagi tuzilmani nusxalash kerak bo'lsa, sayoz nusxalash ishlatiladi. Agar barcha ichki obyektlarni ham nusxalash kerak bo'lsa, chuqur nusxalash ishlatiladi.
  2. Savol: Nusxalash ishlash samaradorligiga qanday ta'sir qiladi? Javob: Chuqur nusxalash sayoz nusxalashga qaraganda ko'proq vaqt va xotira talab qiladi, ayniqsa katta va murakkab obyektlar uchun.
  3. Savol: Nima uchun ba'zan copy.copy() va object.copy() turli natijalar beradi? Javob: copy.copy() obyektning __copy__() metodini chaqiradi, agar u mavjud bo'lsa. object.copy() esa klassdagi maxsus .copy() metodini chaqiradi, agar u aniqlangan bo'lsa.

Qo'shimcha Manbalar

  1. Python rasmiy hujjatlari: copy moduli
  2. Real Python: Shallow vs Deep Copying of Python Objects
  3. Python Tips: Copying
  4. Stack Overflow: Difference between shallow copy, deepcopy and normal assignment operation
  5. Python Software Foundation Wiki: Copy