Python list append causes strange result

前端 未结 5 1273
执念已碎
执念已碎 2021-01-29 00:55

I have really strange problem. Here is the sample code:

class SomeClass(object):
    a = []
    b = []
    def __init__(self, *args, **kwargs):
        self.a =          


        
相关标签:
5条回答
  • 2021-01-29 01:40

    You are assigning the same list to self.b, not a copy.

    If you wanted self.b to refer to a copy of the list, create one using either list() or a full slice:

    self.b = self.a[:]
    

    or

    self.b = list(self.a)
    

    You can test this easily from the interactive interpreter:

    >>> a = b = []  # two references to the same list
    >>> a
    []
    >>> a is b
    True
    >>> a.append(42)
    >>> b
    [42]
    >>> b = a[:]  # create a copy
    >>> a.append(3.14)
    >>> a
    [42, 3.14]
    >>> b
    [42]
    >>> a is b
    False
    
    0 讨论(0)
  • 2021-01-29 01:48

    As many have already mentioned it, you end up having two references on the same list. Modifying the list by one reference of by the other just modify the list.

    Here is an illustration to make things more clear if needed:

    Shared reference

    • Step "A" is just after

      self.a = [(1,2), (3,4)]
      
    • Step "A" is just after

      self.b = self.a
      
    • Step "C" is just after

      self.a.append((5,6))
      
    0 讨论(0)
  • 2021-01-29 01:48

    self.b = self.a isn't copying the list. It's assigning the reference to that list, so both attributes point at the same object. If you modify it via one reference, you'll see the change via the other one too.

    You can use copy.copy(the_list) to get the proper copy. Or copy.deepcopy(the_list) if you need the references below also updated.

    0 讨论(0)
  • 2021-01-29 01:48

    Because self.a and self.b are actually references to the same list object.

    If you want to modify one without changing the other, try this

    class SomeClass(object):
        # a = []
        # b = [] # these two class member not necessary in this code
        def __init__(self, *args, **kwargs):
            self.a = [(1,2), (3,4)]
            self.b = list(self.a) # copy to a new list
            self.a.append((5,6))
            print self.b
    
    SomeClass()
    
    0 讨论(0)
  • 2021-01-29 01:54

    dicts in python share the same memory space when you assign them to each other.

    for more information on this see: http://henry.precheur.org/python/copy_list

    0 讨论(0)
提交回复
热议问题