Ποιες είναι οι επιλογές για να κλωνοποιήσετε ή να αντιγράψετε μια λίστα στην Python;
Κατά τη χρήση της new_list = my_list
, οποιαδήποτε τροποποίηση στη new_list
αλλάζει κάθε φορά τη my_list
.
Γιατί συμβαίνει αυτό;
Με την new_list = my_list
, δεν έχετε στην πραγματικότητα δύο λίστες. Η ανάθεση απλώς αντιγράφει την αναφορά στη λίστα, όχι την πραγματική λίστα, οπότε τόσο η new_list
όσο και η my_list
αναφέρονται στην ίδια λίστα μετά την ανάθεση.
Για να αντιγράψετε πραγματικά τη λίστα, έχετε διάφορες δυνατότητες:
Μπορείτε να χρησιμοποιήσετε την ενσωματωμένη μέθοδο list.copy()
(διαθέσιμη από την Python 3.3):
new_list = old_list.copy()
Μπορείτε να την τεμαχίσετε:
new_list = old_list[:]
Η γνώμη του [Alex Martelli's][1] (τουλάχιστον [πίσω στο 2007][2]) σχετικά με αυτό είναι, ότι είναι ένα περίεργο συντακτικό και δεν έχει νόημα να το χρησιμοποιείτε ποτέ. ;) (Κατά τη γνώμη του, το επόμενο είναι πιο ευανάγνωστο).
Μπορείτε να χρησιμοποιήσετε την ενσωματωμένη συνάρτηση [list()
][3]:
new_list = list(old_list)
Μπορείτε να χρησιμοποιήσετε τη γενική συνάρτηση [copy.copy()
][4]:
import copy
new_list = copy.copy(old_list)
Αυτό είναι λίγο πιο αργό από την list()
επειδή πρέπει πρώτα να βρει τον τύπο δεδομένων της old_list
.
Αν η λίστα περιέχει αντικείμενα και θέλετε να τα αντιγράψετε και αυτά, χρησιμοποιήστε το γενικό [copy.deepcopy()
][5]:
import copy
new_list = copy.deepcopy(old_list)
Προφανώς η πιο αργή και πιο μνημοβόρα μέθοδος, αλλά μερικές φορές αναπόφευκτη.
Παράδειγμα:
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))
Αποτέλεσμα:
original: ['foo', 5, 'baz']
list.copy(): ['foo', 5]
slice: ['foo', 5]
list(): ['foo', 5]
copy: ['foo', 5]
deepcopy: ['foo', 1]
[1]: https://en.wikipedia.org/wiki/Alex_Martelli "Alex Martelli", [2]:
"Bay Area Python Interest Group August 2007 Meeting", [3]: https://docs.python.org/2/library/functions.html#list "list", [4]: https://docs.python.org/2/library/copy.html#copy.copy "copy.copy", [5]: https://docs.python.org/2/library/copy.html#copy.deepcopy "copy.deepcopy",Χρήση thing[:]
>>> a = [1,2]
>>> b = a[:]
>>> a += [3]
>>> a
[1, 2, 3]
>>> b
[1, 2]
>>>