首页 > Python > 如何克隆或复制列表以防止它更改?new_list = my_listnew_listmy_list

如何克隆或复制列表以防止它更改?new_list = my_listnew_listmy_list

上一篇 下一篇

网友问题:
任何修改每次都会更改。为什么会这样,如何克隆或复制列表以防止它?
new_list = my_listnew_listmy_list

分割线

网友回答:

Felix已经提供了一个很好的答案,但我想我会对各种方法进行速度比较:

  1. 10.59 秒 (105.9 微秒/ITN) –copy.deepcopy(old_list)
  2. 10.16 秒 (101.6 μs/itn) – 使用深拷贝的纯 Python 方法复制类Copy()
  3. 1.488 秒 (14.88 μs/itn) – 不复制类的纯 Python 方法(仅字典/列表/元组)Copy()
  4. 0.325 秒 (3.25 微秒/ITN) –for item in old_list: new_list.append(item)
  5. 0.217 秒 (2.17 μs/ITN) – (列表理解)[i for i in old_list]
  6. 0.186 秒 (1.86 微秒/ITN) –copy.copy(old_list)
  7. 0.075 秒 (0.75 微秒/ITN) –list(old_list)
  8. 0.053 秒 (0.53 微秒/ITN) –new_list = []; new_list.extend(old_list)
  9. 0.039 秒 (0.39 μs/ITN) – (列表切片)old_list[:]

所以最快的是列表切片。但请注意,和 不同,python 版本不会复制列表中的任何列表、字典和类实例,因此如果原始版本发生变化,它们也会在复制的列表中发生变化,反之亦然。copy.copy()list[:]list(list)copy.deepcopy()

(如果有人感兴趣或想提出任何问题,这里是脚本:)

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

分割线

网友回答:

new_list = my_list实际上不会创建第二个列表。赋值只是复制对列表的引用,而不是实际列表,因此两者在作业后引用同一列表。new_listmy_list

要实际复制列表,您有以下几种选择:

  • 您可以使用内置方法(从 Python 3.3 开始可用):list.copy()
    new_list = old_list.copy()
    
  • 您可以对其进行切片:
    new_list = old_list[:]
    

    Alex Martelli对此的看法(至少在2007年)是,这是一个奇怪的语法,使用它没有任何意义。? (在他看来,下一个更具可读性)。

  • 您可以使用内置构造函数:list()
    new_list = list(old_list)
    
  • 您可以使用通用:copy.copy()
    import copy
    new_list = copy.copy(old_list)
    

    这比因为它必须首先找出数据类型要慢一些。list()old_list

  • 如果还需要复制列表的元素,请使用通用:copy.deepcopy()
    import copy
    new_list = copy.deepcopy(old_list)
    

    显然是最慢和最需要内存的方法,但有时是不可避免的。这是递归操作的;它将处理任意数量的嵌套列表(或其他容器)级别。

例:

import copy

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

    def __repr__(self):
        return f'Foo({self.val!r})'

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(f'original: {a}nlist.copy(): {b}nslice: {c}nlist(): {d}ncopy: {e}ndeepcopy: {f}')

结果:

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

分割线

网友回答:

有人告诉我,Python 3.3+ 添加了该方法,它应该和切片一样快:list.copy()

newlist = old_list.copy()

模板简介:该模板名称为【如何克隆或复制列表以防止它更改?new_list = my_listnew_listmy_list】,大小是暂无信息,文档格式为.编程语言,推荐使用Sublime/Dreamweaver/HBuilder打开,作品中的图片,文字等数据均可修改,图片请在作品中选中图片替换即可,文字修改直接点击文字修改即可,您也可以新增或修改作品中的内容,该模板来自用户分享,如有侵权行为请联系网站客服处理。欢迎来懒人模板【Python】栏目查找您需要的精美模板。

相关搜索
  • 下载密码 lanrenmb
  • 下载次数 310次
  • 使用软件 Sublime/Dreamweaver/HBuilder
  • 文件格式 编程语言
  • 文件大小 暂无信息
  • 上传时间 02-09
  • 作者 网友投稿
  • 肖像权 人物画像及字体仅供参考
栏目分类 更多 >
热门推荐 更多 >
企业网站 html5 微信公众平台 自适应 微信图片 微信文章 微信模板 微信素材 响应式 单页式简历模板
您可能会喜欢的其他模板