Πώς να κλωνοποιήσετε ή να αντιγράψετε μια λίστα;

Ποιες είναι οι επιλογές για να κλωνοποιήσετε ή να αντιγράψετε μια λίστα στην 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&quot, [2]: https://www.youtube.com/watch?v=g7V89K8QfgQ "Bay Area Python Interest Group August 2007 Meeting&quot, [3]: https://docs.python.org/2/library/functions.html#list "list&quot, [4]: https://docs.python.org/2/library/copy.html#copy.copy "copy.copy&quot, [5]: https://docs.python.org/2/library/copy.html#copy.deepcopy "copy.deepcopy&quot,

Σχόλια (11)

Χρήση thing[:]

>>> a = [1,2]
>>> b = a[:]
>>> a += [3]
>>> a
[1, 2, 3]
>>> b
[1, 2]
>>> 
Σχόλια (0)

Ο ιδιωματισμός της Python για να γίνει αυτό είναι newList = oldList[:]

Σχόλια (0)