猿问

如何克隆或复制列表?

在Python中克隆或复制列表有哪些选项?

在使用时new_list = my_list,每次都会对new_list更改进行任何修改my_list。为什么是这样?


胡说叔叔
浏览 867回答 5
5回答

精慕HU

菲利克斯已经提供了一个很好的答案,但我想我会对各种方法进行速度比较:10.59秒(105.9us / itn) - copy.deepcopy(old_list)10.16秒(101.6us / itn) - Copy()使用deepcopy复制类的纯python 方法1.488秒(14.88us / itn) - 纯python Copy()方法不复制类(只有dicts / lists / tuples)0.325秒(3.25us / itn) - for item in old_list: new_list.append(item)0.217秒(2.17us / itn) - [i for i in old_list](列表理解)0.186秒(1.86us / itn) - copy.copy(old_list)0.075秒(0.75us / itn) - list(old_list)0.053秒(0.53us / itn) - new_list = []; new_list.extend(old_list)0.039秒(0.39us / itn) - old_list[:](列表切片)所以最快的是列表切片。但请注意copy.copy(),list[:]并且list(list),与copy.deepcopy()python版本不同,它不会复制列表中的任何列表,字典和类实例,因此如果原件发生更改,它们也会在复制的列表中更改,反之亦然。(这是脚本,如果有人有兴趣或想提出任何问题:)from copy import deepcopyclass 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 objif __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

鸿蒙传说

我被告知 Python 3.3+ 添加list.copy()方法,它应该像切片一样快:newlist = old_list.copy()

繁花如伊

已经有许多答案告诉你如何制作一个正确的副本,但没有一个人说你为什么原来的'副本'失败了。Python不会将值存储在变量中; 它将名称绑定到对象。您的原始作业采用了所引用的对象并将其my_list绑定new_list。无论您使用哪个名称,仍然只有一个列表,因此在引用它时所做的更改将在引用my_list时保持不变new_list。此问题的其他每个答案都为您提供了创建要绑定的新对象的不同方法new_list。列表的每个元素都像一个名称,因为每个元素都非唯一地绑定到一个对象。浅拷贝创建一个新列表,其元素绑定到与以前相同的对象。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]要使列表副本更进一步,请复制列表引用的每个对象,并将这些元素副本绑定到新列表。import copy   # each element must have __copy__ defined for this...new_list = [copy.copy(element) for element in my_list]这还不是一个深层副本,因为列表的每个元素都可以引用其他对象,就像列表绑定到它的元素一样。以递归方式复制列表中的每个元素,然后复制每个元素引用的每个其他对象,依此类推:执行深层复制。import copy# each element must have __deepcopy__ defined for this...new_list = copy.deepcopy(my_list)有关复制中的边角情况的更多信息,请参阅文档。

沧海一幻觉

使用 thing[:]>>> a = [1,2]>>> b = a[:]>>> a += [3]>>> a[1, 2, 3]>>> b[1, 2]>>> 
随时随地看视频慕课网APP

相关分类

Python
我要回答