Mit new_list = my_list Sie eigentlich nicht haben zwei Listen. Die Zuweisung kopiert den Verweis auf die Liste, nicht die tatsächliche Liste, so dass beide new_list und my_list finden Sie in der gleichen Liste nach der Abtretung ermächtigt.
Eigentlich die Liste kopiert haben, haben Sie verschiedene Möglichkeiten:
Können Sie die builtin Liste.copy() - Methode (verfügbar seit python 3.3):
new_list = old_list.copy()
Können Sie slice it:
new_list = old_list[:]
Alex Martelli ist Meinung nach (zumindest zurück in 2007) über dieses ist, dass es ist eine eigenartige syntax und es macht keinen Sinn, es zu benutzen immer. 😉 (In seiner Meinung, der nächste wird besser lesbar).
Ich 100% Zustimmen. Für eine Antwort auf eine wichtige Python-Frage, das ist ein bisschen verstreut und veraltet. Wenn ich mich nicht verkennen : newlist = [*mylist] ist auch eine Möglichkeit in Python 3. newlist = list(mylist) vielleicht ist mehr klar, obwohl. eine andere Möglichkeit ist new_list = old_list * 1 Welche dieser Methoden sind flache Kopie, und welche von Ihnen sind Tiefe Kopie? alle, aber die Letzte do eine flache Kopie
Also die Schnellste ist die Liste aufschneiden. Aber bewusst sein, dass copy.copy(), list[:] und list(list) im Gegensatz zu copy.deepcopy() und die python-version nicht kopieren, Listen, dictionaries und Klassen-Instanzen in der Liste, so dass, wenn sich die Originale ändern wird, ändern Sie in der kopierten Liste zu und Umgekehrt.
(Hier ist das script, wenn jemand interessiert ist oder will, Ihre möglichen Fragen:)
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}defCopy(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 recursivelyfor 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!passelif 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
BEARBEITEN: neuen Stil, old-style-Klassen und dicts, um die benchmarks, und die python-version viel schneller und fügte einige weitere Methoden, einschließlich der Liste der Ausdrücke und extend().
Da Sie benchmarking, es könnte hilfreich sein, um einen Bezugspunkt. Sind diese zahlen noch genau im Jahr 2017 mit Python 3.6 mit einer voll-kompilierten code? Ich bin in Anbetracht der Antwort unten (stackoverflow.com/a/17810305/26219) bereits Fragen beantwortet. verwenden Sie die timeit Modul. auch, Sie können nicht zu dem Schluss viel aus beliebigen micro-benchmarks wie diesem. Wenn Sie möchten, um eine neue option für 3.5+, [*old_list] sollte in etwa äquivalent zu list(old_list), aber da es die syntax, nicht die Allgemeinen Funktionsaufruf Wege, Sie sparen ein wenig auf die Laufzeit (und im Gegensatz zu old_list[:], die nicht den Typ konvertieren, [*old_list] funktioniert auf jedem durchsuchbar und produziert eine list).
Was sind die Optionen zum duplizieren oder kopieren Sie eine Liste, in Python?
In Python 3, eine flache Kopie gemacht werden kann, mit:
a_copy = a_list.copy()
In Python 2 und 3, können Sie eine flache Kopie mit einer vollen Scheibe des Originals:
a_copy = a_list[:]
Erklärung
Gibt es zwei semantische Möglichkeiten zum kopieren einer Liste. Eine flache Kopie erzeugt eine neue Liste mit der gleichen Objekte, die eine Tiefe Kopie erstellt eine neue Liste mit entsprechenden neuen Objekte.
Flachen Liste kopieren
Wird eine flache Kopie kopiert nur die Liste selbst, die ein container von Referenzen auf die Objekte in der Liste. Wenn die enthaltenen Objekte selbst sind veränderlich und eine geändert wird, die änderung spiegelt sich in beiden Listen.
Gibt es verschiedene Möglichkeiten, dies zu tun in Python 2 und 3. Die Python 2 Möglichkeiten, das funktioniert auch in Python 3.
Python 2
In Python 2 die idiomatische Weise, eine flache Kopie der Liste ist mit einer kompletten Scheibe das original:
a_copy = a_list[:]
Können Sie auch das gleiche erreichen, indem die Liste über die list-Konstruktor,
a_copy = list(a_list)
aber mit dem Konstruktor ist weniger effizient:
>>> timeit
>>> l = range(20)>>> min(timeit.repeat(lambda: l[:]))0.30504298210144043>>> min(timeit.repeat(lambda: list(l)))0.40698814392089844
Python 3
In Python 3, Listen erhalten die list.copy Methode:
Mit new_list = my_list ein, dann ändert new_list jedes mal my_list ein änderungen. Warum ist das so?
my_list ist nur ein name, die Punkte, um die aktuelle Liste im Speicher. Wenn Sie sagen new_list = my_list du bist keine Kopie, du bist einfach nur das hinzufügen eines weiteren Namen die Punkte an, die original-Liste im Speicher. Wir haben ähnliche Probleme, wenn wir Kopien von Listen.
>>> l =[[],[],[]]>>> l_copy = l[:]>>> l_copy
[[],[],[]]>>> l_copy[0].append('foo')>>> l_copy
[['foo'],[],[]]>>> l
[['foo'],[],[]]
Die Liste ist ein array von Zeigern auf die Inhalte, also eine flache Kopie kopiert den Zeiger, und so haben Sie zwei verschiedene Listen, aber Sie haben den gleichen Inhalt. Kopien der Inhalte, die Sie benötigen, eine Tiefe Kopie.
Um zu demonstrieren, wie dies ermöglicht es uns, um eine neue sub-Listen:
>>>import copy
>>> l
[['foo'],[],[]]>>> l_deep_copy = copy.deepcopy(l)>>> l_deep_copy[0].pop()'foo'>>> l_deep_copy
[[],[],[]]>>> l
[['foo'],[],[]]
Und so sehen wir, dass die Tiefe kopiert, die Liste ist eine ganz andere Liste aus dem original. Könnten Sie Rollen Sie Ihre eigene Funktion, aber nicht. Du bist wahrscheinlich zu erstellen, die bugs, die Sie sonst nicht haben durch die Verwendung der standard-Bibliothek deepcopy-Funktion.
Nicht verwenden eval
Können Sie sehen dies als einen Weg, um deepcopy, aber tun Sie es nicht:
problematic_deep_copy = eval(repr(a_list))
Es ist gefährlich, vor allem, wenn Sie die Bewertung etwas aus einer Quelle, die Sie nicht Vertrauen.
Es ist nicht zuverlässig, wenn ein Unterelement Sie kopieren nicht eine Darstellung haben, können eval ' D zu reproduzieren, ein gleichwertiges element.
Sie brauchen nicht eine deepcopy wenn die Liste 2D. Wenn es ist eine Liste von Listen, und diese Listen nicht haben Listen in Ihnen, können Sie eine for-Schleife verwenden. Derzeit bin ich mit list_copy=[]for item in list: list_copy.append(copy(item)) und es ist viel schneller.
Gibt es viele Antworten schon, sagen Sie, wie machen Sie eine richtige Kopie, aber keiner von Ihnen sagen, warum Sie Ihre ursprüngliche 'kopieren' ist fehlgeschlagen.
Python nicht zum speichern von Werten in Variablen, es bindet Namen an Objekte. Ihre ursprüngliche Zuordnung nahm das Objekt bezeichnet, indem my_list gebunden und es new_list als gut. Egal, welchen Namen Sie verwenden, gibt es nur noch eine Liste, mit den änderungen, wenn Sie von sich es als my_list bleiben erhalten, wenn sich auf ihn als new_list. Die anderen Antworten auf diese Frage geben Ihnen verschiedene Möglichkeiten zum erstellen eines neuen Objekts zu binden new_list.
Jedes element einer Liste wirkt wie ein name, in dem jedes element bindet sich nicht exklusiv an ein Objekt. Eine flache Kopie erzeugt eine neue Liste, deren Elemente binden an den gleichen Objekten wie vorher.
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]
Nehmen Sie Ihre Liste kopieren einen Schritt weiter, und kopieren Sie jedes Objekt, dass Ihre Liste sich bezieht, und binden diese element kopiert, um eine neue Liste.
import copy
# each element must have __copy__ defined for this...
new_list =[copy.copy(element)for element in my_list]
Dies ist noch nicht eine Tiefe Kopie, da jedes element einer Liste kann sich auf andere Objekte, so wie die Liste gebunden ist, um seine Elemente. Rekursiv kopieren Sie jedes element in der Liste, und dann jedes andere Objekt bezeichnet, indem jedem element, und so weiter: führen Sie eine Tiefe Kopie.
import copy
# each element must have __deepcopy__ defined for this...
new_list = copy.deepcopy(my_list)
Sehen die Dokumentation für weitere Informationen über corner Fällen zu kopieren.
Alle anderen Mitwirkenden Gaben große Antworten, die arbeiten, wenn Sie eine einzelne dimension (nivelliert) Liste, aber von den genannten Methoden bisher nur copy.deepcopy() Werke zu Klonen/kopieren Sie eine Liste, und Sie müssen nicht zeigen, bis die geschachtelte list Objekte beim arbeiten mit mehrdimensionalen, verschachtelte Listen (Listen von Listen). Während Felix Kling bezieht sich auf Sie in seiner Antwort, es ist ein wenig mehr zu dem Problem und evtl. einen workaround mit built-ins, die beweisen könnte eine schnellere alternative zu deepcopy.
Während new_list = old_list[:], copy.copy(old_list)' und für Py3k old_list.copy() Arbeit für die einzelnen-nivelliert Listen, die Sie wiederherstellen Hinweis auf die list Objekte innerhalb der old_list und die new_list, und änderungen an einer der list Objekte sind verewigt in den anderen.
Edit: Neue Informationen ans Licht gebracht
Als wurde darauf hingewiesen, von beiden Aaron Hall und PM 2Ringmit eval() ist nicht nur eine schlechte Idee, es ist auch viel langsamer als copy.deepcopy().
Dies bedeutet, dass für die mehrdimensionale Listen, die einzige option ist copy.deepcopy(). Mit diesem wird gesagt, es ist nicht wirklich eine option, die Leistung geht Weg in den Süden, wenn Sie versuchen, es auf einen mittleren mehrdimensionales array. Ich habe versucht, zu timeit mit einem 42x42 array, nicht unerhört oder sogar, dass große für Bioinformatik-Anwendungen, und ich gab das warten auf eine Antwort und begann einfach eingeben mein edit an diesem post.
Es scheint, dass die einzige wirkliche option ist dann zu initialisieren, mehrere Listen und arbeiten diese unabhängig voneinander. Wenn jemand noch andere Vorschläge für den Umgang mit mehrdimensionale Liste kopieren, würde es geschätzt werden.
Wie andere gesagt haben, es sind erhebliche performance-Probleme mit der copy Modul und copy.deepcopyfür mehrdimensionale Listen. Versucht, herauszufinden, einen anderen Weg zu kopieren, die mehrdimensionale Liste ohne Verwendung deepcopy (ich war arbeiten an einem problem, für einen Kurs, der es nur erlaubt 5 Sekunden für den gesamten Algorithmus zu laufen, um den Kredit erhalten), ich kam mit ein Weg, mit built-in-Funktionen, um eine Kopie der verschachtelten Liste die zimmerreserviereung, ohne das Sie an einem Punkt oder anderen in der list Objekte verschachtelt. Ich verwendet eval() und repr() in der Zuordnung zu machen, die Kopie der alten Liste in die neue Liste, ohne eine link zu der alten Liste. Es hat die form:
new_list = eval(repr(old_list))
Im Grunde, was das tut, ist eine Darstellung der old_list als string und berechnet dann den string als ob es das Objekt, das die Zeichenkette repräsentiert. Indem er dies tut, keinen link zu dem original list Objekt gemacht wird. Eine neue list - Objekt erstellt und die einzelnen Variablen Punkte, die zu seinem eigenen Objekt. Hier ist ein Beispiel mit einem 2-dimensionalen verschachtelte Liste.
old_list =[[0for j in range(y)]for i in range(x)]# initialize (x,y) nested list# assign a copy of old_list to new list without them pointing to the same list object
new_list = eval(repr(old_list))# make a change to new_list for j in range(y):for i in range(x):
new_list[i][j]+=1
Wenn Sie dann überprüfen Sie den Inhalt der einzelnen Listen, beispielsweise ein 4-3-Liste, Python zurück
Während diesem wahrscheinlich nicht die kanonische oder syntaktisch korrekte Weg, es zu tun, es scheint gut zu funktionieren. Habe ich noch nicht getestet Leistung, aber ich werde zu erraten, dass eval() und rep() haben weniger overhead als deepcopy wird.
Das funktioniert nicht immer, da gibt es keine Garantie, dass der string zurückgegeben, indem repr() ist ausreichend, um das Objekt neu erstellen. Auch eval() ist ein tool von last resort; siehe Eval ist wirklich gefährlich von SO-veteran Ned Batchelder für details. Also, wenn Sie Sie befürworten die Verwendung eval() Sie wirklich sollte erwähnen, dass es gefährlich sein kann. Fairer Punkt. Obwohl ich denke, dass Batchelder der Punkt ist, dass die unter den eval() Funktion in Python im Allgemeinen ist ein Risiko. Es ist nicht so sehr, ob oder nicht Sie nutzen die Funktion im code sondern dass es eine Sicherheitslücke in Python in und von sich selbst. Mein Beispiel ist nicht es mit mit eine Funktion, die eine Eingabe erhält, von input(), sys.agrv oder sogar eine text-Datei. Es ist mehr entlang der Linien initialisieren eine leere mehrdimensionale Liste einmal, und dann nur mit einem Weg zu kopieren in einer Schleife statt reinitialisierung bei jeder iteration der Schleife. @AaronHall hingewiesen hat, ist es wahrscheinlich eine deutliche performance-Problem mit new_list = eval(repr(old_list)), also außer, dass es eine schlechte Idee, es ist wahrscheinlich auch viel zu langsam zu arbeiten.
Let ' s start von Anfang an und Entdecker, die es ein wenig tief :
Also Angenommen, Sie haben zwei Listen :
list_1=['01','98']
list_2=[['01','98']]
Und wir haben zu kopieren Liste , nun ausgehend von der ersten Liste:
Also lassen Sie uns zunächst versuchen, durch Allgemeine Methode zum kopieren:
copy=list_1
Nun, wenn Sie denken kopieren kopiert die list_1, dann können Sie falsch sein, lassen Sie es überprüfen:
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))
Ausgabe:
43294853204329485320
Überrascht ? Ok, lassen Sie uns erforschen:
So, wie wir Sie kennen python nicht speichern alles in einer Variablen, Variablen sind nur in der Bezugnahme auf den Objekt-und Objekt-speichern Sie den Wert. Hier Objekt ist list aber wir zwei Verweise auf das gleiche Objekt durch zwei verschiedene Variablen-Namen. So werden beide Variablen auf das gleiche Objekt :
also, wenn Sie copy=list_1 was eigentlich seine Weise :
Hier im Bild list_1 und kopieren sind zwei Variablen-Namen, aber das Objekt ist die gleiche für beide Variablen, die list
Also, wenn Sie versuchen zu ändern, kopiert die Liste, dann wird es ändern Sie die original-Liste auch, weil die Liste ist nur eine da, Sie zu ändern, dass die Liste keine Angelegenheit, die Sie aus der Liste kopiert oder aus der ursprünglichen Liste:
copy[0]="modify"print(copy)print(list_1)
Ausgabe:
['modify','98']['modify','98']
Also es verändert die ursprüngliche Liste :
Was ist die Lösung?
Lösung :
Lassen Sie uns nun bewegen, um eine zweite pythonic Methode des Kopierens Liste:
copy_1=list_1[:]
Nun diese Methode fix das Ding, was wir konfrontiert waren im ersten Problem lassen Sie uns check it :
Also wie man sehen kann, sind unsere beiden Liste mit verschiedenen id und es bedeutet, dass beide Variablen verweisen auf verschiedene Objekte so, was hier eigentlich Los ist :
Lassen Sie uns nun versuchen, ändern Sie die Liste und lassen Sie uns sehen, ob wir noch vor dem vorherigen problem :
copy_1[0]="modify"print(list_1)print(copy_1)
Ausgabe:
['01','98']['modify','98']
So, wie Sie sehen können ist es nicht eine änderung der ursprünglichen Liste nur modifiziert, kopiert die Liste, Also wir sind ok mit ihm.
So, jetzt denke ich, dass wir fertig sind? warten wir kopieren die zweite verschachtelte Liste zu, so lassen Sie uns versuchen pythonic way :
copy_2=list_2[:]
So list_2 sollte die Referenz zu einem anderen Objekt, das kopieren von list_2 let ' s check:
print(id((list_2)),id(copy_2))
erhalten wir die Ausgabe:
43304035924330403528
Nun können wir davon ausgehen, beide Listen zeigen anderes Objekt so, jetzt lassen Sie uns versuchen, es zu ändern und mal sehen, es gibt, was wir wollen :
Also, wenn wir versuchen:
copy_2[0][1]="modify"print(list_2,copy_2)
es gibt uns-Ausgang:
[['01','modify']][['01','modify']]
Nun, dies ist etwas verwirrend, nutzten wir die pythonic way und immer noch sind wir vor dem gleichen Problem.
lassen Sie uns wissen es:
Also, wenn wir tun :
copy_2=list_2[:]
sind wir eigentlich kopieren der äußeren Liste nur, nicht die verschachtelte Liste, also verschachtelte Liste ist, dasselbe Objekt für Listen, let ' s check:
print(id(copy_2[0]))print(id(list_2[0]))
Ausgabe:
43294858324329485832
Also eigentlich, wenn wir copy_2=list_2[:] dies ist, was passiert:
Schafft es die Kopie der Liste, aber nur die äußere Liste kopieren, nicht die verschachtelte Liste kopieren, verschachtelte Liste ist die gleiche für beide Variablen, so, wenn Sie versuchen, ändern Sie die verschachtelte Liste wird es dann ändern Sie die original-Liste auch, weil die verschachtelte Liste-Objekt ist die gleiche für beide verschachtelte Liste.
Also, was ist die Lösung?
Lösung ist deep copy
from copy import deepcopy
deep=deepcopy(list_2)
So, jetzt lassen Sie uns check it :
print(id((list_2)),id(deep))
Ausgabe:
43221460564322148040
beide id sind unterschiedlich , lassen Sie uns nun überprüfen Sie die verschachtelte Liste-id:
print(id(deep[0]))print(id(list_2[0]))
Ausgabe:
43221459924322145800
Wie Sie sehen können beide id sind Verschieden, so können wir davon ausgehen, dass die verschachtelte Liste nach verschiedenen Objekt jetzt.
Also, wenn Sie deep=deepcopy(list_2) was tatsächlich passiert :
Also sowohl verschachtelte Liste nach verschiedenen Objekt-und haben Sie seprate kopieren von verschachtelten Liste jetzt.
Lassen Sie uns nun versuchen zu ändern, die verschachtelte Liste und mal sehen, ob es löste das Vorherige Problem oder nicht:
also, wenn wir tun :
deep[0][1]="modify"print(list_2,deep)
Ausgabe:
[['01','98']][['01','modify']]
So wie Sie sehen können es nicht ändern Sie die ursprüngliche verschachtelte Liste , es werden nur geänderte kopiert die Liste.
Wenn dir meine ausführliche Antwort , lassen Sie es mich wissen, indem upvoting ,
wenn Sie irgendwelche Zweifel haben realted diese Antwort , Kommentar unten 🙂
Hier sind die zeitlichen Ergebnisse mit Python-3.6.0. Halten Sie im Verstand, den diese Zeiten sind relativ zu anderen, nicht absolut.
Blieb mir tun nur flache Kopien, und fügte auch einige neue Methoden, die nicht möglich ist in Python2, wie list.copy() (die Python ist3 slice entspricht) und Liste Auspacken (*new_list, = list):
METHOD TIME TAKEN
b = a[:]6.468942025996512#Python2 winner
b = a.copy()6.986593422974693#Python3 "slice equivalent"
b =[]; b.extend(a)7.309216841997113
b = a[0:len(a)]10.916740721993847*b,= a 11.046738261007704
b = list(a)11.761539687984623
b =[i for i in a]24.66165203397395
b = copy.copy(a)30.853400873980718
b =[]for item in a:
b.append(item)48.19176080400939
Sehen wir die alten Gewinner kommt immer noch auf top, aber nicht wirklich eine riesige Menge, wenn man bedenkt das erhöht die Lesbarkeit der Python ist3 list.copy() Ansatz.
Beachten Sie, dass diese Methoden nicht nicht Ausgang gleichwertige Ergebnisse für jede Eingabe andere als Listen. Sie alle arbeiten für schneidbar Objekte, ein paar für jeden durchsuchbar, aber nur copy.copy() funktioniert für jedes Python-Objekt.
Sie scheinen zu haben, optimiert die list Initialisierung in Python 3.6.1. Ich habe keine Python-3.6.0 installation, aber b = list(a) bekommt 2.7 und b = a[:] bekommt 3.1, und b = a.copy() bekommt 3.1 (Auf meinem Windows und Linux mit CPython 3.6.1), so list() ist etwa 10% schneller Ich erneut getestet mit Python 3.6.3 (WSL 16.04) und habe im Grunde die gleiche Reihenfolge
Der offensichtliche Nachteil dieser Methode ist, dass Sie nur in Python 3.5+.
Timing klug, aber, das scheint besser als andere gängige Methoden.
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)
Wie funktioniert diese Methode, Verhalten beim ändern von Kopien? meinst du damit das Anhängen oder Bearbeiten von Elementen der neuen Liste. Im Beispiel old_list und new_list sind zwei verschiedene Listen Bearbeiten eines wird sich nicht ändern, die anderen (es sei denn, Sie sind direkt mutierend der Elemente selbst (wie Liste), keine-diese Methoden sind Tiefe Kopien). Ja, ich meinte, wenn die Bearbeitung einer hat auf den anderen. Danke.
Nicht sicher, ob das noch aktuelle ist, aber das gleiche Verhalten gilt auch für die Wörterbücher. Blick auf dieses Beispiel.
a ={'par':[1,21,3],'sar':[5,6,8]}
b = a
c = a.copy()
a['har']=[1,2,3]
a
Out[14]:{'har':[1,2,3],'par':[1,21,3],'sar':[5,6,8]}
b
Out[15]:{'har':[1,2,3],'par':[1,21,3],'sar':[5,6,8]}
c
Out[16]:{'par':[1,21,3],'sar':[5,6,8]}
Beachten Sie, dass es einige Fälle gibt, wenn Sie Ihre eigenen benutzerdefinierten Klasse, und Sie möchten, dass die Attribute dann sollten Sie copy.copy() oder copy.deepcopy() eher als die alternativen, zum Beispiel in Python 3:
import copy
classMyList(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
exceptAttributeError:
name ='NA'print('name: {}'.format(name))
Ausgänge:
lst: original, name: custom list
lst: slicecopy, name: NA
lst: lstcopy, name: NA
lst: copycopy, name: custom list
lst: deepcopy, name: custom list
Einen sehr einfachen Ansatz, unabhängig von der python-version fehlte in den bereits gegebenen Antworten, die Sie verwenden können, die meiste Zeit (zumindest ich):
new_list = my_list *1#Solution 1 when you are not using nested lists
Jedoch, Wenn my_list ein mit anderen Behältnissen (zB. verschachtelte Listen), müssen Sie verwenden deepcopy wie andere vorgeschlagen, in den oben genannten Antworten aus der Bibliothek kopieren. Zum Beispiel:
import copy
new_list = copy.deepcopy(my_list)#Solution 2 when you are using nested lists
.Bonus: Wenn Sie nicht möchten, kopieren Sie Elemente verwenden (auch bekannt als flache Kopie):
new_list = my_list[:]
Lassen Sie uns verstehen den Unterschied zwischen Lösung#1 und Lösung #2
>>> 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])
Wie Sie sehen können Lösung #1 funktionierte perfekt, wenn wir nicht mit den geschachtelten Listen. Lassen Sie uns schauen, was geschehen wird, wenn wir anwenden Lösung #1 verschachtelte Listen.
>>>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
new_list = my_list
Versuchen Sie zu verstehen. Lassen Sie uns sagen, dass my_list ein in den heap-Speicher an der Stelle X, d.h. my_list ein Verweis auf das X. Nun durch die Zuordnung new_list = my_list Sie Lassen new_list zeigt auf den X. Dies ist bekannt als flache Kopie.
Nun, wenn Sie zuweisen new_list = my_list[:] Du bist einfach nur kopieren jedes Objekt der my_list ein bis new_list. Dies ist bekannt als Tiefe Kopie.
Die Andere Möglichkeit, wie Sie dies tun können, sind :
Werden Sie wie zu verwenden deepcopy aus der python standard-Bibliothek.
In python beim kopieren einer Daten-Typ, der ursprünglichen und der kopierten Daten Typen teilen die gleichen Speicherplätze. Folglich änderungen an einer Kopie des Objekts reflektiert wird, in das ursprüngliche Objekt. Zum Beispiel diese:
my_lst=[1,2,3,4,5]#Python listprint my_lst,' my_lst (before copy)'
my_lst_copy = my_lst=[1,2,3,4,5]#Simple copy of python list
my_lst_copy[2]=55#Copy of python list changedprint my_lst_copy,' my_lst_copy (copy of python list)'print my_lst,' my_lst (after copy)'>>>[1,2,3,4,5] my_lst (before copy)>>>[1,2,55,4,5] my_lst_copy (copy of python list)>>>[1,2,55,4,5] my_lst (after copy)
Als Sie bemerkt hatte, bevor, und wie Sie immer wieder feststellen im obigen Beispiel ändern Sie in jedem element der kopierten Liste my_list_cp Veränderungen der ursprünglichen Liste my_list. Der Grund dafür ist, dass es keine neue Zuweisung an my_list_cp.
Können Sie entgegenwirken, die oben mit deepcopy aus der python standard-Bibliothek. In der Tiefe Kopie, wird eine Kopie des Objekts kopiert, in ein anderes Objekt.
from copy import deepcopy
my_lst=[1,2,3,4,5]#Python listprint my_lst,' my_lst (before copy)'
my_lst_copy = deepcopy(my_lst)#Python list copied
my_lst_copy[2]=55#Copy of python list changedprint my_lst_copy,' my_lst_copy (copy of python list)'print my_lst,' my_lst (after copy)'>>>[1,2,3,4,5] my_lst (before copy)>>>[1,2,55,4,5] my_lst_copy (copy of python list)>>>[1,2,3,4,5] my_lst (after copy)
Im obigen Beispiel sehen Sie, dass my_lst hat sich nicht geändert nach dem kopieren.
Mit
new_list = my_list
Sie eigentlich nicht haben zwei Listen. Die Zuweisung kopiert den Verweis auf die Liste, nicht die tatsächliche Liste, so dass beidenew_list
undmy_list
finden Sie in der gleichen Liste nach der Abtretung ermächtigt.Eigentlich die Liste kopiert haben, haben Sie verschiedene Möglichkeiten:
Können Sie die builtin
Liste.copy()
- Methode (verfügbar seit python 3.3):Können Sie slice it:
Alex Martelli ist Meinung nach (zumindest zurück in 2007) über dieses ist, dass es ist eine eigenartige syntax und es macht keinen Sinn, es zu benutzen immer. 😉 (In seiner Meinung, der nächste wird besser lesbar).
Können Sie mit dem eingebauten
Listen()
Funktion:Können generische
kopieren.copy()
:Dies ist ein wenig langsamer als
list()
weil es, um herauszufinden, den Datentypold_list
ersten.Wenn die Liste Objekte enthält, und Sie möchten, um Sie zu kopieren sowie verwenden Sie generische
kopieren.deepcopy()
:Offensichtlich die langsamste und die meisten Speicher benötigen-Methode, aber manchmal unvermeidlich.
Beispiel:
Ergebnis:
Wenn ich mich nicht verkennen :
newlist = [*mylist]
ist auch eine Möglichkeit in Python 3.newlist = list(mylist)
vielleicht ist mehr klar, obwohl.eine andere Möglichkeit ist new_list = old_list * 1
Welche dieser Methoden sind flache Kopie, und welche von Ihnen sind Tiefe Kopie?
alle, aber die Letzte do eine flache Kopie
InformationsquelleAutor Felix Kling
Felix schon eine ausgezeichnete Antwort, aber ich dachte, ich mache einen speed-Vergleich der verschiedenen Methoden:
kopieren.deepcopy(old_list)
Copy()
Methode kopieren von Klassen mit deepcopyCopy()
Methode nicht kopieren-Klassen (nur dicts/Listen/Tupel)for item in old_list: new_list.append(item)
[i for i in old_list]
(a list comprehension)kopieren.kopieren(old_list)
list(old_list)
new_list = []; new_list.extend(old_list)
old_list[:]
(Liste slicing)Also die Schnellste ist die Liste aufschneiden. Aber bewusst sein, dass
copy.copy()
,list[:]
undlist(list)
im Gegensatz zucopy.deepcopy()
und die python-version nicht kopieren, Listen, dictionaries und Klassen-Instanzen in der Liste, so dass, wenn sich die Originale ändern wird, ändern Sie in der kopierten Liste zu und Umgekehrt.(Hier ist das script, wenn jemand interessiert ist oder will, Ihre möglichen Fragen:)
BEARBEITEN: neuen Stil, old-style-Klassen und dicts, um die benchmarks, und die python-version viel schneller und fügte einige weitere Methoden, einschließlich der Liste der Ausdrücke und
extend()
.verwenden Sie die
timeit
Modul. auch, Sie können nicht zu dem Schluss viel aus beliebigen micro-benchmarks wie diesem.Wenn Sie möchten, um eine neue option für 3.5+,
[*old_list]
sollte in etwa äquivalent zulist(old_list)
, aber da es die syntax, nicht die Allgemeinen Funktionsaufruf Wege, Sie sparen ein wenig auf die Laufzeit (und im Gegensatz zuold_list[:]
, die nicht den Typ konvertieren,[*old_list]
funktioniert auf jedem durchsuchbar und produziert einelist
).InformationsquelleAutor cryo
Habe ich gesagt wurde, dass Python 3.3+ fügt der
- Liste.copy()
Methode, die sollte so schnell wie slicing:newlist = old_list.copy()
s.copy()
erstellt eine flache Kopie vons
(gleiche wies[:]
).InformationsquelleAutor anatoly techtonik
In Python 3, eine flache Kopie gemacht werden kann, mit:
In Python 2 und 3, können Sie eine flache Kopie mit einer vollen Scheibe des Originals:
Erklärung
Gibt es zwei semantische Möglichkeiten zum kopieren einer Liste. Eine flache Kopie erzeugt eine neue Liste mit der gleichen Objekte, die eine Tiefe Kopie erstellt eine neue Liste mit entsprechenden neuen Objekte.
Flachen Liste kopieren
Wird eine flache Kopie kopiert nur die Liste selbst, die ein container von Referenzen auf die Objekte in der Liste. Wenn die enthaltenen Objekte selbst sind veränderlich und eine geändert wird, die änderung spiegelt sich in beiden Listen.
Gibt es verschiedene Möglichkeiten, dies zu tun in Python 2 und 3. Die Python 2 Möglichkeiten, das funktioniert auch in Python 3.
Python 2
In Python 2 die idiomatische Weise, eine flache Kopie der Liste ist mit einer kompletten Scheibe das original:
Können Sie auch das gleiche erreichen, indem die Liste über die list-Konstruktor,
aber mit dem Konstruktor ist weniger effizient:
Python 3
In Python 3, Listen erhalten die
list.copy
Methode:In Python 3.5:
Ein weiterer Zeiger ist nicht eine Kopie
my_list
ist nur ein name, die Punkte, um die aktuelle Liste im Speicher. Wenn Sie sagennew_list = my_list
du bist keine Kopie, du bist einfach nur das hinzufügen eines weiteren Namen die Punkte an, die original-Liste im Speicher. Wir haben ähnliche Probleme, wenn wir Kopien von Listen.Die Liste ist ein array von Zeigern auf die Inhalte, also eine flache Kopie kopiert den Zeiger, und so haben Sie zwei verschiedene Listen, aber Sie haben den gleichen Inhalt. Kopien der Inhalte, die Sie benötigen, eine Tiefe Kopie.
Tiefe Kopien
Machen Tiefe Kopie einer Liste, in Python 2 oder 3, verwenden Sie
deepcopy
incopy
- Modul:Um zu demonstrieren, wie dies ermöglicht es uns, um eine neue sub-Listen:
Und so sehen wir, dass die Tiefe kopiert, die Liste ist eine ganz andere Liste aus dem original. Könnten Sie Rollen Sie Ihre eigene Funktion, aber nicht. Du bist wahrscheinlich zu erstellen, die bugs, die Sie sonst nicht haben durch die Verwendung der standard-Bibliothek deepcopy-Funktion.
Nicht verwenden
eval
Können Sie sehen dies als einen Weg, um deepcopy, aber tun Sie es nicht:
In 64-bit-Python 2.7:
auf 64-bit-Python 3.5:
list_copy=[]
for item in list: list_copy.append(copy(item))
und es ist viel schneller.InformationsquelleAutor Aaron Hall
Gibt es viele Antworten schon, sagen Sie, wie machen Sie eine richtige Kopie, aber keiner von Ihnen sagen, warum Sie Ihre ursprüngliche 'kopieren' ist fehlgeschlagen.
Python nicht zum speichern von Werten in Variablen, es bindet Namen an Objekte. Ihre ursprüngliche Zuordnung nahm das Objekt bezeichnet, indem
my_list
gebunden und esnew_list
als gut. Egal, welchen Namen Sie verwenden, gibt es nur noch eine Liste, mit den änderungen, wenn Sie von sich es alsmy_list
bleiben erhalten, wenn sich auf ihn alsnew_list
. Die anderen Antworten auf diese Frage geben Ihnen verschiedene Möglichkeiten zum erstellen eines neuen Objekts zu bindennew_list
.Jedes element einer Liste wirkt wie ein name, in dem jedes element bindet sich nicht exklusiv an ein Objekt. Eine flache Kopie erzeugt eine neue Liste, deren Elemente binden an den gleichen Objekten wie vorher.
Nehmen Sie Ihre Liste kopieren einen Schritt weiter, und kopieren Sie jedes Objekt, dass Ihre Liste sich bezieht, und binden diese element kopiert, um eine neue Liste.
Dies ist noch nicht eine Tiefe Kopie, da jedes element einer Liste kann sich auf andere Objekte, so wie die Liste gebunden ist, um seine Elemente. Rekursiv kopieren Sie jedes element in der Liste, und dann jedes andere Objekt bezeichnet, indem jedem element, und so weiter: führen Sie eine Tiefe Kopie.
Sehen die Dokumentation für weitere Informationen über corner Fällen zu kopieren.
InformationsquelleAutor jack
new_list = list(old_list)
Autor dieser Antwort war "Zuletzt gesehen Feb 4 '12 at 10:48" so ist es unwahrscheinlich, er wird es Bearbeiten.
InformationsquelleAutor user285176
Verwenden
thing[:]
InformationsquelleAutor Paul Tarjan
Python-idiom dafür ist
newList = oldList[:]
InformationsquelleAutor erisco
Im Gegensatz zu anderen Sprachen, die variable und Wert, Python hat name und Objekt.
Diese Aussage:
Mittel zu geben, die Liste (Objekt) einen Namen
a
, und, diese:nur gibt das gleiche Objekt
a
einen neuen Namenb
, so dass, wenn Sie etwas zu tun mita
, der Gegenstand verändert und daherb
änderungen.Der einzige Weg, um eine wirklich Kopie von a ist, erstellen Sie ein neues Objekt wie bei anderen Antworten bereits gesagt haben.
Können Sie sehen, mehr über dieses hier.
InformationsquelleAutor Statham
Alle anderen Mitwirkenden Gaben große Antworten, die arbeiten, wenn Sie eine einzelne dimension (nivelliert) Liste, aber von den genannten Methoden bisher nur
copy.deepcopy()
Werke zu Klonen/kopieren Sie eine Liste, und Sie müssen nicht zeigen, bis die geschachteltelist
Objekte beim arbeiten mit mehrdimensionalen, verschachtelte Listen (Listen von Listen). Während Felix Kling bezieht sich auf Sie in seiner Antwort, es ist ein wenig mehr zu dem Problem und evtl. einen workaround mit built-ins, die beweisen könnte eine schnellere alternative zudeepcopy
.Während
new_list = old_list[:]
,copy.copy(old_list)'
und für Py3kold_list.copy()
Arbeit für die einzelnen-nivelliert Listen, die Sie wiederherstellen Hinweis auf dielist
Objekte innerhalb derold_list
und dienew_list
, und änderungen an einer derlist
Objekte sind verewigt in den anderen.Edit: Neue Informationen ans Licht gebracht
Wie andere gesagt haben, es
sind erhebliche performance-Probleme mit dercopy
Modul undcopy.deepcopy
für mehrdimensionale Listen.Versucht, herauszufinden, einen anderen Weg zu kopieren, die mehrdimensionale Liste ohne Verwendungdeepcopy
(ich war arbeiten an einem problem, für einen Kurs, der es nur erlaubt 5 Sekunden für den gesamten Algorithmus zu laufen, um den Kredit erhalten), ich kam mit ein Weg, mit built-in-Funktionen, um eine Kopie der verschachtelten Liste die zimmerreserviereung, ohne das Sie an einem Punkt oder anderen in derlist
Objekte verschachtelt. Ich verwendeteval()
undrepr()
in der Zuordnung zu machen, die Kopie der alten Liste in die neue Liste, ohne eine link zu der alten Liste. Es hat die form:Im Grunde, was das tut, ist eine Darstellung der
old_list
als string und berechnet dann den string als ob es das Objekt, das die Zeichenkette repräsentiert. Indem er dies tut, keinen link zu dem originallist
Objekt gemacht wird. Eine neuelist
- Objekt erstellt und die einzelnen Variablen Punkte, die zu seinem eigenen Objekt. Hier ist ein Beispiel mit einem 2-dimensionalen verschachtelte Liste.Wenn Sie dann überprüfen Sie den Inhalt der einzelnen Listen, beispielsweise ein 4-3-Liste, Python zurück
Während diesem wahrscheinlich nicht die kanonische oder syntaktisch korrekte Weg, es zu tun, es scheint gut zu funktionieren. Habe ich noch nicht getestet Leistung, aber ich werde zu erraten, dasseval()
undrep()
haben weniger overhead alsdeepcopy
wird.repr()
ist ausreichend, um das Objekt neu erstellen. Aucheval()
ist ein tool von last resort; siehe Eval ist wirklich gefährlich von SO-veteran Ned Batchelder für details. Also, wenn Sie Sie befürworten die Verwendungeval()
Sie wirklich sollte erwähnen, dass es gefährlich sein kann.Fairer Punkt. Obwohl ich denke, dass Batchelder der Punkt ist, dass die unter den
eval()
Funktion in Python im Allgemeinen ist ein Risiko. Es ist nicht so sehr, ob oder nicht Sie nutzen die Funktion im code sondern dass es eine Sicherheitslücke in Python in und von sich selbst. Mein Beispiel ist nicht es mit mit eine Funktion, die eine Eingabe erhält, voninput()
,sys.agrv
oder sogar eine text-Datei. Es ist mehr entlang der Linien initialisieren eine leere mehrdimensionale Liste einmal, und dann nur mit einem Weg zu kopieren in einer Schleife statt reinitialisierung bei jeder iteration der Schleife.@AaronHall hingewiesen hat, ist es wahrscheinlich eine deutliche performance-Problem mit
new_list = eval(repr(old_list))
, also außer, dass es eine schlechte Idee, es ist wahrscheinlich auch viel zu langsam zu arbeiten.InformationsquelleAutor AMR
Also Angenommen, Sie haben zwei Listen :
Und wir haben zu kopieren Liste , nun ausgehend von der ersten Liste:
Also lassen Sie uns zunächst versuchen, durch Allgemeine Methode zum kopieren:
Nun, wenn Sie denken kopieren kopiert die list_1, dann können Sie falsch sein, lassen Sie es überprüfen:
Ausgabe:
Überrascht ? Ok, lassen Sie uns erforschen:
So, wie wir Sie kennen python nicht speichern alles in einer Variablen, Variablen sind nur in der Bezugnahme auf den Objekt-und Objekt-speichern Sie den Wert. Hier Objekt ist
list
aber wir zwei Verweise auf das gleiche Objekt durch zwei verschiedene Variablen-Namen. So werden beide Variablen auf das gleiche Objekt :also, wenn Sie
copy=list_1
was eigentlich seine Weise :Hier im Bild list_1 und kopieren sind zwei Variablen-Namen, aber das Objekt ist die gleiche für beide Variablen, die
list
Also, wenn Sie versuchen zu ändern, kopiert die Liste, dann wird es ändern Sie die original-Liste auch, weil die Liste ist nur eine da, Sie zu ändern, dass die Liste keine Angelegenheit, die Sie aus der Liste kopiert oder aus der ursprünglichen Liste:
Ausgabe:
Also es verändert die ursprüngliche Liste :
Lassen Sie uns nun bewegen, um eine zweite pythonic Methode des Kopierens Liste:
Nun diese Methode fix das Ding, was wir konfrontiert waren im ersten Problem lassen Sie uns check it :
Also wie man sehen kann, sind unsere beiden Liste mit verschiedenen id und es bedeutet, dass beide Variablen verweisen auf verschiedene Objekte so, was hier eigentlich Los ist :
Lassen Sie uns nun versuchen, ändern Sie die Liste und lassen Sie uns sehen, ob wir noch vor dem vorherigen problem :
Ausgabe:
So, wie Sie sehen können ist es nicht eine änderung der ursprünglichen Liste nur modifiziert, kopiert die Liste, Also wir sind ok mit ihm.
So, jetzt denke ich, dass wir fertig sind? warten wir kopieren die zweite verschachtelte Liste zu, so lassen Sie uns versuchen pythonic way :
So list_2 sollte die Referenz zu einem anderen Objekt, das kopieren von list_2 let ' s check:
erhalten wir die Ausgabe:
Nun können wir davon ausgehen, beide Listen zeigen anderes Objekt so, jetzt lassen Sie uns versuchen, es zu ändern und mal sehen, es gibt, was wir wollen :
Also, wenn wir versuchen:
es gibt uns-Ausgang:
Nun, dies ist etwas verwirrend, nutzten wir die pythonic way und immer noch sind wir vor dem gleichen Problem.
lassen Sie uns wissen es:
Also, wenn wir tun :
sind wir eigentlich kopieren der äußeren Liste nur, nicht die verschachtelte Liste, also verschachtelte Liste ist, dasselbe Objekt für Listen, let ' s check:
Ausgabe:
Also eigentlich, wenn wir
copy_2=list_2[:]
dies ist, was passiert:Schafft es die Kopie der Liste, aber nur die äußere Liste kopieren, nicht die verschachtelte Liste kopieren, verschachtelte Liste ist die gleiche für beide Variablen, so, wenn Sie versuchen, ändern Sie die verschachtelte Liste wird es dann ändern Sie die original-Liste auch, weil die verschachtelte Liste-Objekt ist die gleiche für beide verschachtelte Liste.
Also, was ist die Lösung?
Lösung ist
deep copy
So, jetzt lassen Sie uns check it :
Ausgabe:
beide id sind unterschiedlich , lassen Sie uns nun überprüfen Sie die verschachtelte Liste-id:
Ausgabe:
Wie Sie sehen können beide id sind Verschieden, so können wir davon ausgehen, dass die verschachtelte Liste nach verschiedenen Objekt jetzt.
Also, wenn Sie
deep=deepcopy(list_2)
was tatsächlich passiert :Also sowohl verschachtelte Liste nach verschiedenen Objekt-und haben Sie seprate kopieren von verschachtelten Liste jetzt.
Lassen Sie uns nun versuchen zu ändern, die verschachtelte Liste und mal sehen, ob es löste das Vorherige Problem oder nicht:
also, wenn wir tun :
Ausgabe:
So wie Sie sehen können es nicht ändern Sie die ursprüngliche verschachtelte Liste , es werden nur geänderte kopiert die Liste.
Wenn dir meine ausführliche Antwort , lassen Sie es mich wissen, indem upvoting ,
wenn Sie irgendwelche Zweifel haben realted diese Antwort , Kommentar unten 🙂
InformationsquelleAutor Aaditya Ura
Python 3.6.0 Timings
Hier sind die zeitlichen Ergebnisse mit Python-3.6.0. Halten Sie im Verstand, den diese Zeiten sind relativ zu anderen, nicht absolut.
Blieb mir tun nur flache Kopien, und fügte auch einige neue Methoden, die nicht möglich ist in Python2, wie
list.copy()
(die Python ist3 slice entspricht) und Liste Auspacken (*new_list, = list
):Sehen wir die alten Gewinner kommt immer noch auf top, aber nicht wirklich eine riesige Menge, wenn man bedenkt das erhöht die Lesbarkeit der Python ist3
list.copy()
Ansatz.Beachten Sie, dass diese Methoden nicht nicht Ausgang gleichwertige Ergebnisse für jede Eingabe andere als Listen. Sie alle arbeiten für schneidbar Objekte, ein paar für jeden durchsuchbar, aber nur
copy.copy()
funktioniert für jedes Python-Objekt.Hier ist der Test-code für Interessierte (Vorlage von hier):
list
Initialisierung in Python 3.6.1. Ich habe keine Python-3.6.0 installation, aberb = list(a)
bekommt2.7
undb = a[:]
bekommt3.1
, undb = a.copy()
bekommt3.1
(Auf meinem Windows und Linux mit CPython 3.6.1), solist()
ist etwa 10% schnellerIch erneut getestet mit Python 3.6.3 (WSL 16.04) und habe im Grunde die gleiche Reihenfolge
InformationsquelleAutor River
Wundert es mich, dass dies noch nicht erwähnt wurde aber, so der Vollständigkeit halber...
Können Sie ausführen Verzeichnis Auspacken, mit dem "splat-operator":
*
, die auch Elemente kopieren der Liste.Der offensichtliche Nachteil dieser Methode ist, dass Sie nur in Python 3.5+.
Timing klug, aber, das scheint besser als andere gängige Methoden.
meinst du damit das Anhängen oder Bearbeiten von Elementen der neuen Liste. Im Beispiel
old_list
undnew_list
sind zwei verschiedene Listen Bearbeiten eines wird sich nicht ändern, die anderen (es sei denn, Sie sind direkt mutierend der Elemente selbst (wie Liste), keine-diese Methoden sind Tiefe Kopien).Ja, ich meinte, wenn die Bearbeitung einer hat auf den anderen. Danke.
InformationsquelleAutor SCB
Nicht sicher, ob das noch aktuelle ist, aber das gleiche Verhalten gilt auch für die Wörterbücher. Blick auf dieses Beispiel.
InformationsquelleAutor Bobesh
können Sie bulit in der Liste () - Funktion:
ich denke, dieser code wird Ihnen helfen.
InformationsquelleAutor Akash Nayak
Beachten Sie, dass es einige Fälle gibt, wenn Sie Ihre eigenen benutzerdefinierten Klasse, und Sie möchten, dass die Attribute dann sollten Sie
copy.copy()
odercopy.deepcopy()
eher als die alternativen, zum Beispiel in Python 3:Ausgänge:
InformationsquelleAutor Chris_Rands
Einen sehr einfachen Ansatz, unabhängig von der python-version fehlte in den bereits gegebenen Antworten, die Sie verwenden können, die meiste Zeit (zumindest ich):
Jedoch, Wenn my_list ein mit anderen Behältnissen (zB. verschachtelte Listen), müssen Sie verwenden deepcopy wie andere vorgeschlagen, in den oben genannten Antworten aus der Bibliothek kopieren. Zum Beispiel:
.Bonus: Wenn Sie nicht möchten, kopieren Sie Elemente verwenden (auch bekannt als flache Kopie):
Lassen Sie uns verstehen den Unterschied zwischen Lösung#1 und Lösung #2
Wie Sie sehen können Lösung #1 funktionierte perfekt, wenn wir nicht mit den geschachtelten Listen. Lassen Sie uns schauen, was geschehen wird, wenn wir anwenden Lösung #1 verschachtelte Listen.
InformationsquelleAutor jainashish
new_list = my_list
Versuchen Sie zu verstehen. Lassen Sie uns sagen, dass my_list ein in den heap-Speicher an der Stelle X, d.h. my_list ein Verweis auf das X. Nun durch die Zuordnung
new_list = my_list
Sie Lassen new_list zeigt auf den X. Dies ist bekannt als flache Kopie.Nun, wenn Sie zuweisen
new_list = my_list[:]
Du bist einfach nur kopieren jedes Objekt der my_list ein bis new_list. Dies ist bekannt als Tiefe Kopie.Die Andere Möglichkeit, wie Sie dies tun können, sind :
new_list = list(old_list)
import copy
new_list = copy.deepcopy(old_list)
InformationsquelleAutor Ravi Shankar
Werden Sie wie zu verwenden deepcopy aus der python standard-Bibliothek.
In python beim kopieren einer Daten-Typ, der ursprünglichen und der kopierten Daten Typen teilen die gleichen Speicherplätze. Folglich änderungen an einer Kopie des Objekts reflektiert wird, in das ursprüngliche Objekt. Zum Beispiel diese:
Als Sie bemerkt hatte, bevor, und wie Sie immer wieder feststellen im obigen Beispiel ändern Sie in jedem element der kopierten Liste
my_list_cp
Veränderungen der ursprünglichen Listemy_list
. Der Grund dafür ist, dass es keine neue Zuweisung anmy_list_cp
.Können Sie entgegenwirken, die oben mit deepcopy aus der python standard-Bibliothek. In der Tiefe Kopie, wird eine Kopie des Objekts kopiert, in ein anderes Objekt.
Im obigen Beispiel sehen Sie, dass
my_lst
hat sich nicht geändert nach dem kopieren.InformationsquelleAutor Siddharth Satpathy
Können Sie die builtin
list.copy()
Methode (python 3.3+):https://docs.python.org/3/library/copy.html
new_list = old_list.copy()
InformationsquelleAutor Brandon Bailey
in python, wenn Sie den vorgegebenen Wert für variable und wenn Sie zugewiesen, die variable in eine andere,
zweite variable hat nur Referenz anstelle von kopierten Wert.
also, wenn Sie etwas ändern in l & k wird zu reflektieren beide.. so seine aufeinander verweisen statt coping
kopieren verwenden [::]
InformationsquelleAutor Silent Spectator