Initializing 2D lists in Python: How to make deep copies of each row?

前端 未结 2 1231
鱼传尺愫
鱼传尺愫 2021-01-18 11:48

Let\'s say I want to initialize a 2D Python list with all 0\'s, I\'d do something like:

test = [[0.0] * 10] * 10

Then I start modifying val

相关标签:
2条回答
  • 2021-01-18 12:14

    Doing [[0.0] * 10] * 10actually creates multiple copies of the same list so modifying one will affect all of them:

    >>> test = [[0.0] * 10] * 10
    >>> [id(x) for x in test]     #see all IDs are same
    [3065020524L, 3065020524L, 3065020524L, 3065020524L, 3065020524L, 3065020524L, 3065020524L, 3065020524L, 3065020524L, 3065020524L]
    

    Try this:

    >>> test = [[0.0]*10 for _ in xrange(10)]
    >>> test[0][0] = 1.0
    >>> test
    [[1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]]
    

    Integers/floats are immutable, while lists are mutable:

    >>> x = y = []
    >>> x is y       # Both point to the same object
    True 
    >>> x.append(1)  # list.extend modifies a list in-place
    >>> x,y          # both references to [] can see the modification
    ([1], [1])
    >>> x = y = 1
    >>> x is y      #both points to the same object
    True
    >>> x+=1        # only x gets modified, it now points to a new object 2
    >>> x,y         # y still points to the same object 1
    (2, 1)
    
    0 讨论(0)
  • 2021-01-18 12:25

    The list test contains multiple iterations of the same list, hence a change in one (as you are making by reassigning the first element of test[0]) is reflected in all the others. Try this instead:

    [[0.0]*10 for _ in xrange(10)]  # or `range` in Python 3.x
    

    Of course, you wouldn't need to worry about this if all you had was [0.0] * 10, since this creates a list of ints, none of which can ever mutate. Lists, on the other hand, are indeed mutable.

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