Bir liste nas─▒l kopyalan─▒r veya kopyalan─▒r?


Al─▒nan cevaba git


Python'da bir listeyi klonlamak veya kopyalamak i├žin se├ženekler nelerdir?

Kullan─▒rken new_list = my_list , herhangi bir de─či┼čiklik new_list de─či┼čiklikleri my_list Her zaman. Bu neden?


2244





2010-04-10




Cevap say─▒s─▒n─▒ say: 15






─░le new_list = my_list asl─▒nda iki listeniz yok. Atama sadece kopya listesine referans─▒ de─čil, fiili liste, hem bu y├╝zden new_list ve my_list g├Ârevden sonra ayn─▒ listeye bak─▒n.

Listeyi kopyalamak i├žin ├že┼čitli olas─▒l─▒klara sahipsiniz:

  • Yerle┼čik list.copy() y├Ântemi kullanabilirsiniz (Python 3.3'ten beri kullan─▒labilir):

     new_list = old_list.copy()
     
  • Dilimleyebilirsiniz:

     new_list = old_list[:]
     

    Alex Martelli'nin (en az─▒ndan 2007'de ) bu konudaki g├Âr├╝┼č├╝ , garip bir s├Âzdizimi oldu─ču ve onu kullanmak hi├ž mant─▒kl─▒ gelmiyor . ;) (Ona g├Âre bir sonraki daha okunakl─▒).

  • Yerle┼čik i┼člevi kullanabilirsiniz list() :

     new_list = list(old_list)
     
  • Genel kullanabilirsiniz copy.copy() :

     import copy
    new_list = copy.copy(old_list)
     

    Bu biraz daha yava┼čt─▒r list() ├ž├╝nk├╝ old_list ilk veri tipini bulmak zorundad─▒r .

  • Listede nesneler varsa ve bunlar─▒ da kopyalamak istiyorsan─▒z, jenerik kullan─▒n copy.deepcopy() :

     import copy
    new_list = copy.deepcopy(old_list)
     

    A├ž─▒k├žas─▒ en yava┼č ve en ├žok bellek gerektiren y├Ântem, ancak bazen ka├ž─▒n─▒lmaz.

├ľrnek:

 import copy

class Foo(object):
    def __init__(self, val):
         self.val = val

    def __repr__(self):
        return str(self.val)

foo = Foo(1)

a = ['foo', foo]
b = a.copy()
c = a[:]
d = list(a)
e = copy.copy(a)
f = copy.deepcopy(a)

# edit orignal list and instance 
a.append('baz')
foo.val = 5

print('original: %r\n list.copy(): %r\n slice: %r\n list(): %r\n copy: %r\n deepcopy: %r'
      % (a, b, c, d, e, f))
 

Sonu├ž:

 original: ['foo', 5, 'baz']
list.copy(): ['foo', 5]
slice: ['foo', 5]
list(): ['foo', 5]
copy: ['foo', 5]
deepcopy: ['foo', 1]
 

2981







Felix zaten m├╝kemmel bir cevap verdi, ancak ├že┼čitli y├Ântemlerle h─▒z kar┼č─▒la┼čt─▒rmas─▒ yapaca─č─▒m─▒ d├╝┼č├╝nd├╝m:

  1. 10.59 sn (105.9us / saat) - copy.deepcopy(old_list)
  2. 10.16 sn (101.6us / itn) - derin Copy() kopyalamal─▒ s─▒n─▒flar─▒ kopyalayan saf python y├Ântemi
  3. 1.488 sn (14.88us / itn) - Copy() s─▒n─▒flar─▒ kopyalamayan saf python y├Ântemi (yaln─▒zca dikte / listeler / kay─▒tlar)
  4. 0.325 sn (3.25us / saat) - for item in old_list: new_list.append(item)
  5. 0.217 sn (2.17us / itn) - [i for i in old_list] (bir liste anlama )
  6. 0.186 sn (1.86us / itn) - copy.copy(old_list)
  7. 0.075 sn (0.75us / dn) - list(old_list)
  8. 0,053 sn (0,53us / saat) - new_list = []; new_list.extend(old_list)
  9. 0.039 sn (0.39us / itn) - old_list[:] ( liste dilimleme )

Yani en h─▒zl─▒ liste dilimlemedir. Ancak copy.copy() , list[:] ve python s├╝r├╝m├╝n├╝n list(list) aksine copy.deepcopy() listedeki listeleri, s├Âzl├╝kleri ve s─▒n─▒f ├Ârneklerini kopyalamad─▒─č─▒n─▒ unutmay─▒n; bu nedenle orijinaller de─či┼čirse, kopyalanan listede de de─či┼čeceklerdir.

(Birisi ilgilenen ya da herhangi bir sorunu dile getirmek istiyorsa senaryo burada :)

 from copy import deepcopy

class old_class:
    def __init__(self):
        self.blah = 'blah'

class new_class(object):
    def __init__(self):
        self.blah = 'blah'

dignore = {str: None, unicode: None, int: None, type(None): None}

def Copy(obj, use_deepcopy=True):
    t = type(obj)

    if t in (list, tuple):
        if t == tuple:
            # Convert to a list if a tuple to 
            # allow assigning to when copying
            is_tuple = True
            obj = list(obj)
        else: 
            # Otherwise just do a quick slice copy
            obj = obj[:]
            is_tuple = False

        # Copy each item recursively
        for x in xrange(len(obj)):
            if type(obj[x]) in dignore:
                continue
            obj[x] = Copy(obj[x], use_deepcopy)

        if is_tuple: 
            # Convert back into a tuple again
            obj = tuple(obj)

    elif t == dict: 
        # Use the fast shallow dict copy() method and copy any 
        # values which aren't immutable (like lists, dicts etc)
        obj = obj.copy()
        for k in obj:
            if type(obj[k]) in dignore:
                continue
            obj[k] = Copy(obj[k], use_deepcopy)

    elif t in dignore: 
        # Numeric or string/unicode? 
        # It's immutable, so ignore it!
        pass 

    elif use_deepcopy: 
        obj = deepcopy(obj)
    return obj

if __name__ == '__main__':
    import copy
    from time import time

    num_times = 100000
    L = [None, 'blah', 1, 543.4532, 
         ['foo'], ('bar',), {'blah': 'blah'},
         old_class(), new_class()]

    t = time()
    for i in xrange(num_times):
        Copy(L)
    print 'Custom Copy:', time()-t

    t = time()
    for i in xrange(num_times):
        Copy(L, use_deepcopy=False)
    print 'Custom Copy Only Copying Lists/Tuples/Dicts (no classes):', time()-t

    t = time()
    for i in xrange(num_times):
        copy.copy(L)
    print 'copy.copy:', time()-t

    t = time()
    for i in xrange(num_times):
        copy.deepcopy(L)
    print 'copy.deepcopy:', time()-t

    t = time()
    for i in xrange(num_times):
        L[:]
    print 'list slicing [:]:', time()-t

    t = time()
    for i in xrange(num_times):
        list(L)
    print 'list(L):', time()-t

    t = time()
    for i in xrange(num_times):
        [i for i in L]
    print 'list expression(L):', time()-t

    t = time()
    for i in xrange(num_times):
        a = []
        a.extend(L)
    print 'list extend:', time()-t

    t = time()
    for i in xrange(num_times):
        a = []
        for y in L:
            a.append(y)
    print 'list append:', time()-t

    t = time()
    for i in xrange(num_times):
        a = []
        a.extend(i for i in L)
    print 'generator expression extend:', time()-t
 

552


2010-04-10





Ben ettik s├Âylendi Python 3.3+ oldu─čunu ekler list.copy() dilimleme kadar h─▒zl─▒ olmal─▒d─▒r y├Ântemi:

newlist = old_list.copy()


138







Python'da bir listeyi klonlamak veya kopyalamak i├žin se├ženekler nelerdir?

Python 3'te, a┼ča─č─▒dakilerle s─▒─č bir kopya olu┼čturulabilir:

 a_copy = a_list.copy()
 

Python 2 ve 3'te, orijinalin tam bir dilimiyle s─▒─č bir kopya alabilirsiniz:

 a_copy = a_list[:]
 

a├ž─▒klama

Bir listeyi kopyalaman─▒n iki anlamsal yolu vard─▒r. S─▒─č bir kopya, ayn─▒ nesnelerin yeni bir listesini olu┼čturur, derin bir kopya, yeni e┼čde─čer nesneleri i├žeren yeni bir liste olu┼čturur.

S─▒─č liste kopyas─▒

S─▒─č bir kopya yaln─▒zca listenin kendisini kopyalar; bu, listedeki nesnelere ba┼čvurular─▒n bir kab─▒d─▒r. E─čer i├žerdikleri nesneler de─či┼čebilirse ve bir tanesi de─či┼čtirilirse, de─či┼čiklik her iki listeye de yans─▒r.

Bunu Python 2 ve 3'te yapman─▒n farkl─▒ yollar─▒ vard─▒r. Python 2 yollar─▒ Python 3'te de ├žal─▒┼čacakt─▒r.

Python 2

Python 2'de, listenin s─▒─č bir kopyas─▒n─▒ yapman─▒n aptalca yolu, orijinalin tam bir dilimidir:

 a_copy = a_list[:]
 

Ayn─▒ ┼čeyi listeyi liste kurucusundan ge├žirerek de yapabilirsiniz.

 a_copy = list(a_list)
 

ancak yap─▒c─▒y─▒ kullanmak daha az etkilidir:

 >>> timeit
>>> l = range(20)
>>> min(timeit.repeat(lambda: l[:]))
0.30504298210144043
>>> min(timeit.repeat(lambda: list(l)))
0.40698814392089844
 

Python 3

Python 3'te listeler ┼ču list.copy y├Ântemi al─▒r:

 a_copy = a_list.copy()
 

Python 3.5'te:

 >>> import timeit
>>> l = list(range(20))
>>> min(timeit.repeat(lambda: l[:]))
0.38448613602668047
>>> min(timeit.repeat(lambda: list(l)))
0.6309100328944623
>>> min(timeit.repeat(lambda: l.copy()))
0.38122922903858125
 

Ba┼čka bir i┼čaret├ži yapma gelmez de─čil bir kopyas─▒n─▒

New_list = my_list kullanmak, my_list her de─či┼čti─činde new_list'i de─či┼čtirir. Bu neden?

my_list sadece bellekteki ger├žek listeye i┼čaret eden bir isimdir. Kopyalamad─▒─č─▒n─▒z─▒ s├Âylerken new_list = my_list , sadece haf─▒zadaki o orijinal listeye i┼čaret eden ba┼čka bir isim ekliyorsunuz. Listeleri kopyalarken benzer sorunlar─▒ ya┼čayabiliriz.

 >>> l = [[], [], []]
>>> l_copy = l[:]
>>> l_copy
[[], [], []]
>>> l_copy[0].append('foo')
>>> l_copy
[['foo'], [], []]
>>> l
[['foo'], [], []]
 

Liste yaln─▒zca i├žeri─če bir i┼čaret├ži dizisidir, bu nedenle s─▒─č bir kopya i┼čaret├žileri kopyalar ve bu nedenle iki farkl─▒ listeniz vard─▒r, ancak ayn─▒ i├žeri─če sahiptirler. ─░├žeri─čin kopyalar─▒n─▒ ├ž─▒karmak i├žin derin bir kopyaya ihtiyac─▒n─▒z var.

Derin kopyalar

Bir yapmak i├žin Python 2 veya 3'te bir listenin derin kopyas─▒n─▒ kullanmak deepcopy i├žinde copy mod├╝l :

 import copy
a_deep_copy = copy.deepcopy(a_list)
 

Bunun yeni alt listeler yapmam─▒za nas─▒l izin verdi─čini g├Âstermek i├žin:

 >>> import copy
>>> l
[['foo'], [], []]
>>> l_deep_copy = copy.deepcopy(l)
>>> l_deep_copy[0].pop()
'foo'
>>> l_deep_copy
[[], [], []]
>>> l
[['foo'], [], []]
 

Ve b├Âylece, kopyalanan listenin orijinalden tamamen farkl─▒ bir liste oldu─čunu g├Âr├╝yoruz. Kendi i┼člevini alabilirsin - ama yapma. Standart k├╝t├╝phanenin derin kopya i┼člevini kullanarak, aksi takdirde sahip olamayaca─č─▒n─▒z b├Âcekler yaratma ihtimaliniz y├╝ksektir.

Kullanma eval

Bunun, deepcopy y├Ântemi olarak kullan─▒ld─▒─č─▒n─▒ g├Ârebilirsiniz, ancak yapmay─▒n:

 problematic_deep_copy = eval(repr(a_list))
 
  1. Tehlikeli, ├Âzellikle g├╝vendi─činiz bir kaynaktan bir ┼čeyi de─čerlendirirseniz.
  2. G├╝venilir de─čil, kopyalad─▒─č─▒n─▒z bir alt ├Â─če, e┼čde─čer bir ├Â─čeyi ├žo─čaltmak i├žin de─čerlendirilebilecek bir g├Âsterime sahip de─čilse.
  3. Ayn─▒ zamanda daha az performans.

64 bit Python 2.7'de:

 >>> import timeit
>>> import copy
>>> l = range(10)
>>> min(timeit.repeat(lambda: copy.deepcopy(l)))
27.55826997756958
>>> min(timeit.repeat(lambda: eval(repr(l))))
29.04534101486206
 

64 bit Python 3.5 ├╝zerinde:

 >>> import timeit
>>> import copy
>>> l = list(range(10))
>>> min(timeit.repeat(lambda: copy.deepcopy(l)))
16.84255409205798
>>> min(timeit.repeat(lambda: eval(repr(l))))
34.813894678023644
 

120







Size d├╝zg├╝n bir kopyalaman─▒n nas─▒l yap─▒ld─▒─č─▒n─▒ s├Âyleyen bir├žok cevap var, ancak hi├žbiri orijinal 'kopyan─▒z─▒n' neden ba┼čar─▒s─▒z oldu─čunu s├Âylemedi.

Python de─čerleri de─či┼čkenlerde saklamaz; adlar─▒ nesnelere ba─člar. Orijinal ├Âdeviniz, ba┼čvurulan nesneyi ald─▒ ve ayn─▒ zamanda my_list ona da ba─člad─▒ new_list . Hangi ismi kullan─▒rsan─▒z kullan─▒n hala tek bir liste var, o y├╝zden ona at─▒fta bulunurken, ona at─▒fta bulunurken yap─▒lan de─či┼čiklikler my_list devam edecek new_list . Bu soruya verilen di─čer cevaplar─▒n her biri size ba─članacak yeni bir nesne olu┼čturman─▒n farkl─▒ yollar─▒n─▒ sunar new_list .

Bir listenin her eleman─▒ bir isim gibi davran─▒r, ├ž├╝nk├╝ her eleman yaln─▒zca bir nesneye ba─članmaz. S─▒─č kopya, elemanlar─▒ ├Ânceden oldu─ču gibi ayn─▒ nesnelere ba─članan yeni bir liste olu┼čturur.

 new_list = list(my_list)  # or my_list[:], but I prefer this syntax
# is simply a shorter way of:
new_list = [element for element in my_list]
 

Listenizi bir ad─▒m daha ileri g├Ât├╝rmek i├žin, listenizin ba┼čvurdu─ču her nesneyi kopyalay─▒n ve bu ├Â─če kopyalar─▒n─▒ yeni bir listeye ba─člay─▒n.

 import copy  
# each element must have __copy__ defined for this...
new_list = [copy.copy(element) for element in my_list]
 

Bu hen├╝z derin bir kopya de─čildir, ├ž├╝nk├╝ listedeki her ├Â─če, listedeki ├Â─čelere ba─čl─▒ oldu─ču gibi di─čer nesnelere de g├Ânderme yapabilir. Listedeki her ├Â─čeyi ve ard─▒ndan her ├Â─čenin adland─▒rd─▒─č─▒ her nesneyi yinelemeli olarak kopyalamak i├žin: derin bir kopya ger├žekle┼čtirin.

 import copy
# each element must have __deepcopy__ defined for this...
new_list = copy.deepcopy(my_list)
 

Kopyalamadaki k├Â┼če davalar─▒ hakk─▒nda daha fazla bilgi i├žin belgelere bak─▒n .


51


2014-11-23





kullan─▒m thing[:]

 >>> a = [1,2]
>>> b = a[:]
>>> a += [3]
>>> a
[1, 2, 3]
>>> b
[1, 2]
>>> 
 

34







Python'un bunu yapt─▒─č─▒ tabiri newList = oldList[:]


32







Python 3.6 Zamanlamalar─▒

─░┼čte Python 3.6.8 kullanan zamanlama sonu├žlar─▒. Unutmay─▒n, bu zamanlar birbirleriyle g├Ârecelidir, mutlak de─čildir.

Sadece s─▒─č kopyalar yapmay─▒ ba┼čard─▒m list.copy() ve Python2'de (Python3 dilim e┼čde─čeri ) ve a├žmak i├žin iki liste bi├žimi ( *new_list, = list ve new_list = [*list] ) gibi m├╝mk├╝n olmayan baz─▒ yeni y├Ântemler de ekledim :

 METHOD                  TIME TAKEN
b = [*a]                2.75180600000021
b = a * 1               3.50215399999990
b = a[:]                3.78278899999986  # Python2 winner (see above)
b = a.copy()            4.20556500000020  # Python3 "slice equivalent" (see above)
b = []; b.extend(a)     4.68069800000012
b = a[0:len(a)]         6.84498999999959
*b, = a                 7.54031799999984
b = list(a)             7.75815899999997
b = [i for i in a]      18.4886440000000
b = copy.copy(a)        18.8254879999999
b = []
for item in a:
  b.append(item)        35.4729199999997
 

Python2 kazanan─▒n─▒n hala iyi ├žal─▒┼čt─▒─č─▒n─▒ g├Âr├╝yoruz, ancak Python3'├╝ list.copy() , ├Âzellikle ikincisinin ├╝st├╝n okunabilirli─či g├Âz ├Ân├╝ne al─▒nd─▒─č─▒nda ├žok fazla ├Âne ├ž─▒karm─▒yor .

Koyu at, b = [*a] ├ži─č dilimlemeden ~% 25 daha h─▒zl─▒ olan ve di─čer ambalaj a├žma y├Ânteminden ( *b, = a ) iki kat daha h─▒zl─▒ olan a├žma ve yeniden paketleme y├Ântemidir ( ).

b = a * 1 Ayr─▒ca ┼ča┼č─▒rt─▒c─▒ derecede iyi.

Bu y├Ântemlerin listeler d─▒┼č─▒ndaki girdiler i├žin e┼čde─čer sonu├žlar vermedi─čini unutmay─▒n . Hepsi dilimlenebilir nesneler i├žin, birka├ž yinelenebilir i┼č i├žin copy.copy() ├žal─▒┼č─▒r , ancak daha genel Python nesneleri i├žin ├žal─▒┼č─▒r.


─░lgili taraflar i├žin test kodu: ( Buradan ┼čablon ):

 import timeit

COUNT = 50000000
print("Array duplicating. Tests run", COUNT, "times")
setup = 'a = [0,1,2,3,4,5,6,7,8,9]; import copy'

print("b = list(a)\t\t", timeit.timeit(stmt='b = list(a)', setup=setup, number=COUNT))
print("b = copy.copy(a)\t", timeit.timeit(stmt='b = copy.copy(a)', setup=setup, number=COUNT))
print("b = a.copy()\t\t", timeit.timeit(stmt='b = a.copy()', setup=setup, number=COUNT))
print("b = a[:]\t\t", timeit.timeit(stmt='b = a[:]', setup=setup, number=COUNT))
print("b = a[0:len(a)]\t\t", timeit.timeit(stmt='b = a[0:len(a)]', setup=setup, number=COUNT))
print("*b, = a\t\t\t", timeit.timeit(stmt='*b, = a', setup=setup, number=COUNT))
print("b = []; b.extend(a)\t", timeit.timeit(stmt='b = []; b.extend(a)', setup=setup, number=COUNT))
print("b = []; for item in a: b.append(item)\t", timeit.timeit(stmt='b = []\nfor item in a:  b.append(item)', setup=setup, number=COUNT))
print("b = [i for i in a]\t", timeit.timeit(stmt='b = [i for i in a]', setup=setup, number=COUNT))
print("b = [*a]\t\t", timeit.timeit(stmt='b = [*a]', setup=setup, number=COUNT))
print("b = a * 1\t\t", timeit.timeit(stmt='b = a * 1', setup=setup, number=COUNT))
 

22







Ba┼čtan ba┼člayal─▒m ve biraz derinle┼čtirelim:

Diyelim ki iki listeniz var:

 list_1=['01','98']
list_2=[['01','98']]
 

Ve ┼čimdi birinci listeden ba┼člayarak her iki listeyi de kopyalamam─▒z gerekiyor:

├ľyleyse ilk olarak genel kopya y├Ântemini deneyelim:

 copy=list_1
 

┼×imdi kopyan─▒n list_1'i kopyalad─▒─č─▒n─▒ d├╝┼č├╝n├╝yorsan─▒z o zaman yanl─▒┼č olabilirsiniz, kontrol edelim:

 The id() function shows us that both variables point to the same list object, i.e. they share this object.
 
 print(id(copy))
print(id(list_1))
 

├ž─▒kt─▒:

 4329485320
4329485320
 

┼×a┼č─▒rd─▒n m─▒? Tamam, ke┼čfedelim:

Python'un bir de─či┼čkende hi├žbir ┼čey saklamad─▒─č─▒n─▒ bildi─čimiz i├žin De─či┼čkenler sadece nesneye at─▒fta bulunur ve nesne de─čeri saklar. Burada nesne list ancak ayn─▒ nesneye iki farkl─▒ de─či┼čken ad─▒yla iki referans olu┼čturduk. Yani her iki de─či┼čken de ayn─▒ nesneyi i┼čaret ediyor:

yani copy=list_1 asl─▒nda ne yapt─▒─č─▒n─▒ yapt─▒─č─▒n─▒zda:


g├Âr├╝nt├╝ tan─▒m─▒n─▒ buraya girin

Burada resim list_1 ve kopyas─▒nda iki de─či┼čken ad─▒ var, ancak nesne her iki de─či┼čken i├žin ayn─▒ list

Bu nedenle, kopyalanan listeyi de─či┼čtirmeye ├žal─▒┼č─▒rsan─▒z, liste yaln─▒zca orada oldu─čundan orijinal listeyi de de─či┼čtirir, kopyalanan listeden veya orijinal listeden ne yaparsan─▒z yap─▒n bu listeyi de─či┼čtirirsiniz:

 copy[0]="modify"

print(copy)
print(list_1)
 

├ž─▒kt─▒:

 ['modify', '98']
['modify', '98']
 

B├Âylece orijinal listeyi de─či┼čtirdi:

O zaman ├ž├Âz├╝m nedir?

├ç├Âz├╝m :

┼×imdi ikinci bir pythonic kopyalama listesi y├Ântemine ge├želim:

 copy_1=list_1[:]
 

┼×imdi bu y├Ântemle ilk say─▒m─▒zda kar┼č─▒la┼čt─▒─č─▒m─▒z ┼čeyi d├╝zeltelim:

 print(id(copy_1))
print(id(list_1))

4338792136
4338791432
 

Her iki listemizde farkl─▒ bir kimli─če sahip oldu─čumuzu g├Ârebildi─čimiz ve bu her iki de─či┼čkenin de farkl─▒ nesnelere i┼čaret etti─či anlam─▒na gelir.


g├Âr├╝nt├╝ tan─▒m─▒n─▒ buraya girin

┼×imdi listeyi de─či┼čtirmeye ├žal─▒┼čal─▒m ve bir ├Ânceki sorunla kar┼č─▒ kar┼č─▒ya m─▒ kald─▒─č─▒m─▒z─▒ g├Ârelim:

 copy_1[0]="modify"

print(list_1)
print(copy_1)
 

Çıktı:

 ['01', '98']
['modify', '98']
 

G├Ârd├╝─č├╝n├╝z gibi orijinal listeyi de─či┼čtirmiyor, sadece kopyalanan listeyi de─či┼čtirdi, yani biz tamam─▒z.

Yani ┼čimdi bitti─čimizi d├╝┼č├╝n├╝yorum? bekleyin ikinci yuvalanm─▒┼č listeyi de kopyalamam─▒z gerekiyor, bu y├╝zden pythonic yolu deneyelim:

 copy_2=list_2[:]
 

Bu y├╝zden list_2, list_2'nin kopyas─▒ olan ba┼čka bir nesneye referans verelim:

 print(id((list_2)),id(copy_2))
 

├ž─▒kt─▒y─▒ al─▒yoruz:

 4330403592 4330403528
 

┼×imdi her iki listenin de farkl─▒ bir nesneyi i┼čaret etti─čini varsayabiliriz, bu y├╝zden ┼čimdi de─či┼čtirmeye ├žal─▒┼čal─▒m ve istedi─čimizi verdi─čini g├Ârelim:

Yani denedi─čimizde:

 copy_2[0][1]="modify"

print(list_2,copy_2)
 

bize ├ž─▒kt─▒ verir:

 [['01', 'modify']] [['01', 'modify']]
 

┼×imdi, bu pitonik yolu kulland─▒─č─▒m─▒z i├žin biraz kafa kar─▒┼čt─▒r─▒c─▒ ve yine de ayn─▒ sorunla kar┼č─▒ kar┼č─▒yay─▒z.

Hadi anlayal─▒m:

Peki yapt─▒─č─▒m─▒z zaman:

 copy_2=list_2[:]
 

asl─▒nda i├ž i├že ge├žmi┼č listeyi de─čil, yaln─▒zca d─▒┼č listeyi kopyal─▒yoruz, bu nedenle i├ž i├že ge├žmi┼č liste her iki liste i├žin de ayn─▒ nesnedir:

 print(id(copy_2[0]))
print(id(list_2[0]))
 

├ž─▒kt─▒:

 4329485832
4329485832
 

Yani asl─▒nda bunu yapt─▒─č─▒m─▒zda olan copy_2=list_2[:] ┼čey:


g├Âr├╝nt├╝ tan─▒m─▒n─▒ buraya girin

Listenin kopyas─▒n─▒ olu┼čturur, ancak i├ž i├že liste kopyas─▒n─▒ de─čil, yaln─▒zca d─▒┼č liste kopyas─▒n─▒ de─čil, i├ž i├že ge├žmi┼č liste her iki de─či┼čken i├žin ayn─▒d─▒r, bu nedenle i├ž i├že ge├žmi┼č listeyi de─či┼čtirmeye ├žal─▒┼č─▒rsan─▒z, i├ž i├že ge├žmi┼č liste nesnesinin her ikisi i├žin de ayn─▒ oldu─čundan, orijinal listeyi de de─či┼čtirir i├ž i├že liste.

├ľyleyse ├ž├Âz├╝m nedir?

├ç├Âz├╝m deep copy

 from copy import deepcopy
deep=deepcopy(list_2)
 

┼×imdi kontrol edelim:

 print(id((list_2)),id(deep))
 

├ž─▒kt─▒:

 4322146056 4322148040
 

Her iki kimlik farkl─▒, ┼čimdi i├ž i├že ge├žmi┼č liste kimli─čini kontrol edelim:

 print(id(deep[0]))
print(id(list_2[0]))
 

├ž─▒kt─▒:

 4322145992
4322145800
 

Her iki kimli─čin de farkl─▒ oldu─čunu g├Ârebildi─činiz i├žin, her iki i├ž i├že listenin de art─▒k farkl─▒ bir nesneyi i┼čaret etti─čini varsayabiliriz.

Peki, deep=deepcopy(list_2) ger├žekte olanlar─▒ yapt─▒─č─▒n─▒zda:


g├Âr├╝nt├╝ tan─▒m─▒n─▒ buraya girin

Yani her iki i├ž i├že liste farkl─▒ bir nesneyi i┼čaret ediyor ve i├ž i├že ge├žmi┼č listenin ayr─▒ bir kopyas─▒n─▒ ┼čimdi al─▒yorlar.

┼×imdi i├ž i├že ge├žmi┼č listeyi de─či┼čtirmeye ├žal─▒┼čal─▒m ve ├Ânceki sorunu ├ž├Âz├╝p ├ž├Âzmedi─čine bakal─▒m:

├Âyleyse yaparsak:

 deep[0][1]="modify"
print(list_2,deep)
 

├ž─▒kt─▒:

 [['01', '98']] [['01', 'modify']]
 

G├Ârd├╝─č├╝n├╝z gibi orijinal i├ž i├že ge├žmi┼č listeyi de─či┼čtirmedi, yaln─▒zca kopyalanan listeyi de─či┼čtirdi.

E─čer ayr─▒nt─▒l─▒ cevab─▒m─▒ be─čenirseniz, bu cevab─▒ ger├žekle┼čtirdi─činiz konusunda ┼č├╝pheniz varsa, yorumla bana bildirin, :)


21







Di─čer t├╝m kat─▒l─▒mc─▒lar, tek bir boyut (seviye) listeniz oldu─čunda i┼če yarayan, ancak ┼ču ana kadar bahsedilen y├Ântemlerden yaln─▒zca olu┼čan bir listeyi klonlamak / kopyalamak i├žin ├žal─▒┼čt─▒─č─▒n─▒z ve i├ž i├že ge├žmi┼č nesnelere i┼čaret etmedi─činiz i├žin ├žal─▒┼čan harika cevaplar verdi. ├žok boyutlu, yuvalanm─▒┼č listelerle ├žal─▒┼čma (listeler listesi). Felix Kling , cevab─▒nda buna at─▒fta bulunurken , konuya biraz daha fazla ve muhtemelen daha h─▒zl─▒ bir alternatif sa─člayabilecek yerle┼čikleri kullanan bir ge├žici ├ž├Âz├╝m var . copy.deepcopy() list https://stackoverflow.com/users/218196/felix-kling deepcopy

Py3k i├žin tek seviyeli listelerde ├žal─▒┼č─▒rken new_list = old_list[:] , i├žinde ve i├žinde bulunan nesneleri i┼čaret etmeye geri d├Ânerler ve nesnelerden birinde yap─▒lan de─či┼čiklikler di─čerinde s├╝rd├╝r├╝l├╝r. copy.copy(old_list)' old_list.copy() list old_list new_list list

D├╝zenleme: Yeni bilgiler ─▒┼č─▒─ča getirildi

Her iki taraf─▒ndan i┼čaret edildi─či gibi Aaron Hall ve PM 2Ring kullanarak eval() ├žok daha yava┼č da sadece k├Ât├╝ bir fikir de─čildir copy.deepcopy() .

Bunun anlam─▒, ├žok boyutlu listeler i├žin tek se├žene─čin olmas─▒d─▒r copy.deepcopy() . Oldu─ču s├Âyleniyor, ger├žekten orta boyutlu ├žok boyutlu bir dizi ├╝zerinde kullanmaya ├žal─▒┼čt─▒─č─▒n─▒zda performans g├╝neye gidiyor gibi ger├žekten bir se├ženek de─čildir. timeit Biyoinformatik uygulamalar─▒ i├žin duyulmam─▒┼č hatta o kadar b├╝y├╝k olmayan bir 42x42 dizisi kullanmaya ├žal─▒┼čt─▒m ve bir yan─▒t beklemekten vazge├žtim ve d├╝zenlememi bu yaz─▒ya yazmaya ba┼člad─▒m.

├ľyleyse tek se├ženek, birden fazla listeyi ba┼člatmak ve ba─č─▒ms─▒z olarak ├žal─▒┼čmakt─▒r. Herhangi birinin ba┼čka bir ├Ânerisi varsa, ├žok boyutlu liste kopyalaman─▒n nas─▒l yap─▒laca─č─▒ ile ilgili olarak, takdir edilecektir.

Di─čerlerinin de belirtti─či gibi, mod├╝l├╝ kullanarak ve ├žok boyutlu listeler i├žin ├Ânemli performans sorunlar─▒ var . copy copy.deepcopy


18


2015-07-10





Bu hen├╝z s├Âylenmemi┼č olmas─▒ beni ┼ča┼č─▒rt─▒yor, bu y├╝zden taml─▒k u─čruna ...

* Listenizdeki unsurlar─▒ da kopyalayacak olan "splat operat├Âr├╝": ile paket a├žma listesini yapabilirsiniz.

 old_list = [1, 2, 3]

new_list = [*old_list]

new_list.append(4)
old_list == [1, 2, 3]
new_list == [1, 2, 3, 4]
 

Bu y├Ântemin olumsuz taraf─▒, yaln─▒zca Python 3.5+ s├╝r├╝m├╝nde mevcut olmas─▒d─▒r.

Ak─▒ll─▒ca zamanlama olsa da, bu di─čer yayg─▒n y├Ântemlerden daha iyi performans g├Âsteriyor gibi g├Âr├╝n├╝yor.

 x = [random.random() for _ in range(1000)]

%timeit a = list(x)
%timeit a = x.copy()
%timeit a = x[:]

%timeit a = [*x]

#: 2.47 ┬Ás ┬▒ 38.1 ns per loop (mean ┬▒ std. dev. of 7 runs, 100000 loops each)
#: 2.47 ┬Ás ┬▒ 54.6 ns per loop (mean ┬▒ std. dev. of 7 runs, 100000 loops each)
#: 2.39 ┬Ás ┬▒ 58.2 ns per loop (mean ┬▒ std. dev. of 7 runs, 100000 loops each)

#: 2.22 ┬Ás ┬▒ 43.2 ns per loop (mean ┬▒ std. dev. of 7 runs, 100000 loops each)
 

11


2018-02-26





Kendi ├Âzel s─▒n─▒f─▒n─▒z─▒ tan─▒mlad─▒ysan─▒z ve ├Âznitelikleri korumak istiyorsan─▒z , ├Ârne─čin Python 3'te alternatifleri kullanmak yerine copy.copy() veya bunlar─▒ kullanman─▒z gereken baz─▒ durumlar oldu─čunu unutmay─▒n copy.deepcopy() :

 import copy

class MyList(list):
    pass

lst = MyList([1,2,3])

lst.name = 'custom list'

d = {
'original': lst,
'slicecopy' : lst[:],
'lstcopy' : lst.copy(),
'copycopy': copy.copy(lst),
'deepcopy': copy.deepcopy(lst)
}


for k,v in d.items():
    print('lst: {}'.format(k), end=', ')
    try:
        name = v.name
    except AttributeError:
        name = 'NA'
    print('name: {}'.format(name))
 

Çıktılar:

 lst: original, name: custom list
lst: slicecopy, name: NA
lst: lstcopy, name: NA
lst: copycopy, name: custom list
lst: deepcopy, name: custom list
 

6







Python versiyonundan ba─č─▒ms─▒z ├žok basit bir yakla┼č─▒m, ├žo─ču zaman kullanabilece─činiz zaten verilen cevaplarda eksikti (en az─▒ndan ben yapar─▒m):

 new_list = my_list * 1       #Solution 1 when you are not using nested lists
 

Bununla birlikte, my_list ba┼čka kapsay─▒c─▒lar i├žeriyorsa (├Ârne─čin, yuvalanm─▒┼č listeler i├žin), yukar─▒da verilen cevaplarda kopyalanan k├╝t├╝phaneden ├Ânerilen di─čerleri gibi derin kopya kullanman─▒z gerekir. ├ľrne─čin:

 import copy
new_list = copy.deepcopy(my_list)   #Solution 2 when you are using nested lists
 

. Bonus : Kullan─▒m elemanlar─▒n─▒ kopyalamak istemiyorsan─▒z (aka s─▒─č kopya):

 new_list = my_list[:]
 

├ç├Âz├╝m # 1 ve ├ç├Âz├╝m # 2 aras─▒ndaki fark─▒ anlayal─▒m

 >>> a = range(5)
>>> b = a*1
>>> a,b
([0, 1, 2, 3, 4], [0, 1, 2, 3, 4])
>>> a[2] = 55 
>>> a,b
([0, 1, 55, 3, 4], [0, 1, 2, 3, 4])
 

G├Ârd├╝─č├╝n├╝z gibi, i├ž i├že ge├žmi┼č listeleri kullanmad─▒─č─▒m─▒z zaman, ├ç├Âz├╝m # 1 m├╝kemmel ├žal─▒┼čt─▒. 1 numaral─▒ ├ž├Âz├╝m├╝ i├ž i├že listelere uygulad─▒─č─▒m─▒zda ne olaca─č─▒n─▒ kontrol edelim.

 >>> from copy import deepcopy
>>> a = [range(i,i+4) for i in range(3)]
>>> a
[[0, 1, 2, 3], [1, 2, 3, 4], [2, 3, 4, 5]]
>>> b = a*1
>>> c = deepcopy(a)
>>> for i in (a, b, c): print i   
[[0, 1, 2, 3], [1, 2, 3, 4], [2, 3, 4, 5]]
[[0, 1, 2, 3], [1, 2, 3, 4], [2, 3, 4, 5]]
[[0, 1, 2, 3], [1, 2, 3, 4], [2, 3, 4, 5]]
>>> a[2].append('99')
>>> for i in (a, b, c): print i   
[[0, 1, 2, 3], [1, 2, 3, 4], [2, 3, 4, 5, 99]]
[[0, 1, 2, 3], [1, 2, 3, 4], [2, 3, 4, 5, 99]]   #Solution#1 didn't work in nested list
[[0, 1, 2, 3], [1, 2, 3, 4], [2, 3, 4, 5]]       #Solution #2 - DeepCopy worked in nested list
 

5







 new_list = my_list[:]
 

new_list = my_list Bunu anlamaya ├žal─▒┼č. Diyelim ki my_list ├Âbek haf─▒zas─▒nda X konumunda. Diyelim ki my_list X'e i┼čaret ediyor. ┼×imdi, X new_list = my_list i┼čaretini i┼čaret ederek yeni listeye izin veriyorsunuz. Buna s─▒─č Kopya denir.

┼×imdi new_list = my_list[:] atarsan─▒z, my_list'in her nesnesini new_list'e kopyalaman─▒z yeterlidir. Bu Derin kopya olarak bilinir.

Bunu yapman─▒n di─čer yolu:

  • new_list = list(old_list)
  • import copy new_list = copy.deepcopy(old_list)

3







Di─čer baz─▒ cevaplardan sonra biraz farkl─▒ bir ┼čey g├Ândermek istedim. Bu, muhtemelen en anla┼č─▒l─▒r veya en h─▒zl─▒ se├ženek olmasa da, derin kopyalaman─▒n nas─▒l ├žal─▒┼čt─▒─č─▒n─▒n yan─▒ s─▒ra, derin kopyalama i├žin ba┼čka bir alternatif se├ženek olarak da i├žeriden bir g├Âr├╝nt├╝ sunar. Fonksiyonumun hatalar─▒ olup olmad─▒─č─▒ ├Ânemli de─čil, ├ž├╝nk├╝ bunun amac─▒, soru cevaplar─▒ gibi nesneleri kopyalaman─▒n bir yolunu g├Âstermek, ayn─▒ zamanda bunu, ├Âz├╝nde ├žekirde─čin derinlemesine nas─▒l ├žal─▒┼čt─▒─č─▒n─▒ a├ž─▒klamak i├žin bir nokta olarak kullanmakt─▒r.

Herhangi bir derin kopyalama fonksiyonunun ├Âz├╝nde, s─▒─č bir kopya olu┼čturman─▒n yolu vard─▒r. Nas─▒l? Basit. Herhangi bir derin kopyalama i┼člevi, yaln─▒zca de─či┼čtirilemeyen nesnelerin kaplar─▒n─▒ ├žo─čalt─▒r. Yuvalanm─▒┼č bir listeyi derinlemesine ald─▒─č─▒n─▒zda, listelerin i├žindeki de─či┼čken nesneleri de─čil, yaln─▒zca d─▒┼č listeleri ├žo─čalt─▒rs─▒n─▒z. Sadece kaplar─▒ kopyal─▒yorsunuz. Ayn─▒ ┼čey s─▒n─▒flar i├žin de ge├žerlidir. Bir s─▒n─▒f─▒ derinlemesine ald─▒─č─▒n─▒zda, de─či┼čken ├Âzelliklerinin t├╝m├╝n├╝ derinlemesine ├žekersiniz. Nas─▒l? Neden yaln─▒zca kapsay─▒c─▒lar─▒, listeler, al─▒nt─▒lar, tuples, iters, s─▒n─▒flar ve s─▒n─▒f ├Ârnekleri gibi kopyalaman─▒z gerekiyor?

Basit. De─či┼čtirilebilir bir nesne ger├žekten ├žo─čalt─▒lamaz. Asla de─či┼čtirilemez, bu y├╝zden sadece tek bir de─čerdir. Bu, hi├žbir zaman dizeleri, say─▒lar─▒, boolleri veya bunlardan herhangi birini ├žo─čaltman─▒z gerekmedi─či anlam─▒na gelir. Ama kaplar─▒ nas─▒l kopyalars─▒n─▒z? Basit. T├╝m de─čerleri i├žeren yeni bir kapsay─▒c─▒ ba┼člatt─▒n─▒z. Deepcopy ├Âzyinelemeye dayan─▒r. T├╝m kaplar, i├žinde kaplar olmasa bile, kaplar kalmayana kadar ├žo─čal─▒r. Bir konteyner de─či┼čmez bir nesnedir.

Bunu ├Â─črendikten sonra, bir nesneyi referans olmadan tamamen kopyalamak olduk├ža kolayd─▒r. Temel veri t├╝rlerini derinlemesine basmaya y├Ânelik bir i┼člev: (├Âzel s─▒n─▒flar i├žin i┼če yaramaz, ancak bunu her zaman ekleyebilirsiniz)

 def deepcopy(x):
  immutables = (str, int, bool, float)
  mutables = (list, dict, tuple)
  if isinstance(x, immutables):
    return x
  elif isinstance(x, mutables):
    if isinstance(x, tuple):
      return tuple(deepcopy(list(x)))
    elif isinstance(x, list):
      return [deepcopy(y) for y in x]
    elif isinstance(x, dict):
      values = [deepcopy(y) for y in list(x.values())]
      keys = list(x.keys())
      return dict(zip(keys, values))
 

Python'un kendi yerle┼čik deepcopy'si bu ├Ârne─če dayan─▒yor. Aradaki tek fark, di─čer t├╝rleri desteklemesi ve ayr─▒ca nitelikleri yeni bir yinelenen s─▒n─▒fa kopyalayarak kullan─▒c─▒ s─▒n─▒flar─▒n─▒ desteklemesi ve ayr─▒ca bir not listesi veya s├Âzl├╝k kullanarak daha ├Ânce g├Ârd├╝─č├╝ bir nesneye referansla sonsuz yinelemeyi engellemesidir. Ve bu ger├žekten derin kopyalar yapmak i├žin. ├ľz├╝nde, derin bir kopya yapmak sadece s─▒─č kopyalar yapmakt─▒r. Umar─▒m bu cevap soruya bir ┼čeyler ekler.

├ľRNEKLER

Bu listeye sahip oldu─čunuzu s├Âyleyin: [1, 2, 3] . De─či┼čmez say─▒lar ├žo─čalt─▒lamaz, ancak di─čer katman olabilir. Bir liste kavrama kullanarak ├žo─čaltabilirsiniz: [[1, 2, 3] 'te x i├žin x

┼×imdi, bu listeye sahip oldu─čunuzu hayal edin: [[1, 2], [3, 4], [5, 6]] . Bu kez, listenin t├╝m katmanlar─▒n─▒ derinlemesine kopyalamak i├žin ├Âzyinelemeyi kullanan bir i┼člev yapmak istiyorsunuz. ├ľnceki liste yerine anlama:

 [x for x in _list]
 

Listeler i├žin yeni bir tane kullan─▒r:

 [deepcopy_list(x) for x in _list]
 

Ve deepcopy_list ┼č├Âyle g├Âr├╝n├╝r:

 def deepcopy_list(x):
  if isinstance(x, (str, bool, float, int)):
    return x
  else:
    return [deepcopy_list(y) for y in x]
 

O zaman ┼čimdi herhangi bir strs, bools, floast, ints ve hatta listeleri yinelemeyi kullanarak sonsuz say─▒da katmana derinle┼čtirebilecek bir i┼čleve sahipsiniz . Ve i┼čte orada, derin kopya.

TLDR : Deepcopy, nesneleri ├žo─čaltmak i├žin ├Âzyinelemeyi kullan─▒r ve de─či┼čmez nesneler ├žo─čalt─▒lamad─▒─č─▒ndan, yaln─▒zca ├Ânceden oldu─ču gibi de─či┼čtirilemez nesneleri d├Ând├╝r├╝r. Bununla birlikte, bir nesnenin en d─▒┼čtaki de─či┼čken katman─▒na ula┼čana kadar en de─či┼čken i├ž nesnelerin katmanlar─▒n─▒ derinle┼čtirir.


0



─░lgili yay─▒nlar


Git'teki t├╝m uzak dallar nas─▒l klonlan─▒r?

Bir Date nesnesini klonlamak nas─▒l?

Git deposunu belirli revizyon / de─či┼čiklik setiyle nas─▒l klonlayabilirim?

ArrayList nas─▒l kopyalan─▒r ve i├žeri─či nas─▒l kopyalan─▒r?

Bir vaka s─▒n─▒f─▒ ├Ârne─či nas─▒l kopyalan─▒r ve Scala'da yaln─▒zca bir alan de─či┼čtirilir?

.NET genel S├Âzl├╝k <string, T> klonlama / derin kopyalaman─▒n en iyi yolu nedir?

InputStream nas─▒l klonlan─▒r?

T├╝m liste ├Â─čelerinin ayn─▒ de─čere sahip olup olmad─▒─č─▒n─▒ kontrol etmek ve onu d├Ând├╝rmek veya e─čer yoksa bir ÔÇťotherValueÔÇŁ d├Ând├╝rmek nas─▒l?

Nodejs: Bir nesnenin nas─▒l kopyalanaca─č─▒

Eclipse ├çal─▒┼čma Alan─▒n─▒ Klonlama

Etiketle ilgili di─čer sorular [python]


JavaScript tarihi nas─▒l bi├žimlendirilir?

Geri ├ža─čr─▒ i├žinde do─čru `this` nas─▒l eri┼čilir?

belirtilen port numaras─▒ ile scp

Ge├žici bir tablo olup olmad─▒─č─▒n─▒ kontrol edin ve ge├žici bir tablo olu┼čturmadan ├Ânce mevcut olup olmad─▒─č─▒n─▒ silin.

ÔÇťCat << EOFÔÇŁ bashta nas─▒l ├žal─▒┼č─▒r?

Listenin dize g├Âsterimini listeye d├Ân├╝┼čt├╝r

Nas─▒l java.util.Date i├žin java.sql.Date d├Ân├╝┼čt├╝rmek i├žin?

Toplu i┼č i├žeren bir klas├Âr olu┼čturun, ancak hen├╝z mevcut de─čilse

Statik ba─člama ve dinamik ba─člant─▒

Java Aray├╝zleri / Uygulama adland─▒rma kural─▒ [kopya]