代码之家  ›  专栏  ›  技术社区  ›  Mohd Maaz Giri

在for循环中获取空列表[重复]

  •  0
  • Mohd Maaz Giri  · 技术社区  · 6 年前

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

    使用时 new_list = my_list ,任何修改 new_list 变化 my_list 每次。 这是为什么?

    0 回复  |  直到 6 年前
        1
  •  0
  •   Corman    6 年前

    new_list = my_list ,实际上没有两个列表。作业只是复制对列表的引用,而不是实际的列表,因此 new_list my_list 作业结束后,参考同一清单。

    要实际复制列表,您有多种可能性:

    • 你可以用内置的 list.copy() 方法(从Python3.3开始提供):

      new_list = old_list.copy()
      
    • 你可以切开它:

      new_list = old_list[:]
      

      Alex Martelli's 意见(至少 back in 2007 )关于这个,那个 这是一种奇怪的语法,使用它是没有意义的 . (在他看来,下一个更具可读性)。

    • 你可以使用内置的 list() 功能:

      new_list = list(old_list)
      
    • 你可以用通用的 copy.copy() :

      import copy
      new_list = copy.copy(old_list)
      

      这比 列表() 因为它必须找出 old_list 第一。

    • 如果列表包含对象,并且您也希望复制它们,请使用generic 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 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]
    
        2
  •  -1
  •   Aka    5 年前

    费利克斯已经给出了一个很好的答案,但我想我应该对各种方法做一个速度比较:

    1. 10.59秒(105.9us/itn)- copy.deepcopy(old_list)
    2. 10.16秒(101.6us/itn)-纯python Copy() 方法使用deepcopy复制类
    3. 1.488秒(14.88us/itn)-纯蟒蛇 复制() 方法不复制类(仅dict/list/tuple)
    4. 0.325秒(3.25us/itn)- for item in old_list: new_list.append(item)
    5. 0.217秒(2.17us/itn)- [i for i in old_list] (一) list comprehension )
    6. 0.186秒(1.86us/itn)- copy.copy(old_list)
    7. 0.075秒(0.75us/itn)- list(old_list)
    8. 0.053秒(0.53us/itn)- new_list = []; new_list.extend(old_list)
    9. 0.039秒(0.39us/itn)- old_list[:] ( list slicing )

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

    (如果有人感兴趣或想提出任何问题,请看下面的脚本:)

    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