I want to rewrite only one element of the list in Python 3.

Asked 2 years ago, Updated 2 years ago, 35 views

[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,

I wanted to make a list that says

>>def makeboard():
    _ = [0 for i in range (5) ]
    board=[_for i in range(5)]
    return board
>>board=makeboard()
>>board
[[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]]
>>board[2][2] = 1
>>board
[[0, 0, 1, 0, 0], [0, 0, 1, 0, 0], [0, 0, 1, 0, 0], [0, 0, 1, 0, 0], [0, 0, 1, 0, 0]]

It has become like that.Maybe it's because it's a shallow copy.

>>import copy
>>board=copy.deepcopy(makeboard())
>>board[2][2] = 1

Even if you try it like that

>>board
[[0, 0, 1, 0, 0], [0, 0, 1, 0, 0], [0, 0, 1, 0, 0], [0, 0, 1, 0, 0], [0, 0, 1, 0, 0]]

nothing changed.What should I do?Please tell me the reason as well.

python python3

2022-09-29 22:22

2 Answers

Use the id(object) to examine the contents of the board variable (list type).

id(object)

Return the "identity" of an object.This is an integer which is guaranteed to be unique and constant for this object during its lifetime.Two objects with non-overlapping lifetimes may have the same id() value.
 CPython implementation detail:This is the address of the object in memory.

>>def makeboard():
      _ = [0 for i in range (5) ]
      board=[_for i in range(5)]
      return board
>>board=makeboard()
>> for i, bin enumerate (board):
      print(f'board[{i}] = {hex(id(b))}')

board[0] = 0x7f81d81bc840
board[1] = 0x7f81d81bc840
board[2] = 0x7f81d81bc840
board[3] = 0x7f81d81bc840
board [4] = 0x7f81d81bc840

I can see that the instance id(memory address) is all the same.Then try copy.deepcopy() as the question states.

>>import copy
>>board=copy.deepcopy(makeboard())
>> for i, bin enumerate (board):
      print(f'board[{i}] = {hex(id(b))}')

board [0] = 0x7f98c8f85800
board[1] = 0x7f98c8f85800
board[2] = 0x7f98c8f85800
board [3] = 0x7f98c8f85800
board [4] = 0x7f98c8f85800

The instance id(memory address) is all the same here.You can find the reason by looking at here and here.

def_deepcopy_list(x,memo,deepcopy=deepcopy):
    y = [ ]
    memo [id(x)] = y
    append = y.append
    For a in x:
        append(deepcopy(a,memo))
    returny

d[list] =_deepcopy_list

def deepcopy(x,memo=None,_nil=[]):
    Deep copy operation on arbitrary Python objects.
    See the module's__doc_string for more info.
    """

    if memo is None:
        memo={}

    d = id(x)
    y=memo.get(d,_nil)
    if y is not_nil:
        returny
           :

In for a in x:append(deepcopy(a,memo)) of the _deepcopy_list() function, the instance id(memory address) of board[0] to board[4] is all the same, so the memory address of is

In order to avoid the above, deepcopy is done in its original sense, but create a separate instance when the makeboard function runs.

>>def makeboard(w,h):
>> return [[0]*w for_in range(h)]

>>board=makeboard(5,5)
>>board[2][2] = 1
>> print (board)
[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]

>> for i, bin enumerate (board):
>>print(f'board[{i}]={hex(id(b))}')

board[0] = 0x7f8dcef49900
board[1] = 0x7f8dcef49940
board[2] = 0x7f8dcef49840
board [3] = 0x7f8dcef49800
board [4] = 0x7f8dcef45600

There is another way to use numpy.

>>import numpy as np
>> board=np.zeros(5,5), dtype=int)
>>board [2,2] = 1
>>board
array([0,0,0,0,0,0],
       [0, 0, 0, 0, 0],
       [0, 0, 1, 0, 0],
       [0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0]])


2022-09-29 22:22

 [obj for_in range(n)] 

Generate a list with n elements that reference the same obj when you write

_=[0 for i in range(5)]
board=[_for i in range(5)]

This is

 board = [[0,0,0,0,0] for i in range(5)]

This means that you will generate a list of five elements that reference a single [0,0,0,0,0] object.

 board = [[0 for_in range(5)] for_in range(5)]

Then you can generate five [0,0,0,0,0] objects with five elements that reference the same 0 and generate a list of elements.

board=[0]*5 for_in range(5)] 

You can generate five [0,0,0,0,0] objects with five elements that reference the same 0 as the , and generate a list using them as elements.

In addition,

board=[0]*5]*5

For a [0,0,0,0,0] object with five elements that reference the same 0,0,0,0 will generate a list with five elements that reference this single [0,0,0,0,0].

All Python variables and container elements are reference variables and reference elements.
(The reference refers to constraints, but is equivalent to references in other languages.Java and C# references, which are different from C++ references.)
I think it's easy to understand that variables and container elements contain references to real objects.


2022-09-29 22:22

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.