First question here, so go easy on me.
I am attempting to assign a list of objects which represent an accumulator of 1s and 0s at each index location of a large input of binary strings ex: 011011101.
I wanted to read the first row of my input to get the length of the binary string, and then assign a variable that looks like -> "[ {0:0, 1:0} ] * len(n)" for the sake of brevity, I know that all rows will be a length of 12.
My objective: loop over each item in a row, and add 1 to either the 1 or 0 at that index location's object key. -> "arr[i][v] = 1"
i represents both the string index AND the object I want to access in the dynamically sized array
v represents the key(0 or 1) of the object at i location that i want to increment by 1
In this way I can figure out how many 1s or 0s are at each position of a given input.
simplified code: ` input = ["010101101100", "110001101101"] arr = [{ 0:0,1:0 }] * len(input[0])
for row in input: for i, v in enumerate(row): v = int(v) arr[i][v] = 1 print(arr) `
WRONG Result!
However, if I explicitly set the list as such:
input = ["010101101100", "110001101101"]
arr = [
{ 0:0,1:0 },
{ 0:0,1:0 },
{ 0:0,1:0 },
{ 0:0,1:0 },
{ 0:0,1:0 },
{ 0:0,1:0 },
{ 0:0,1:0 },
{ 0:0,1:0 },
{ 0:0,1:0 },
{ 0:0,1:0 },
{ 0:0,1:0 },
{ 0:0,1:0 }
]
for i, v in enumerate(input):
v = int(v)
arr[i][v] = 1
print(arr)
The correct Answer!
What exactly is going on here? Why is the loop that accesses the dynamic list applying the addition to each object and corresponding key-value pair?
I'm sure it is some computer science thing that I'm just not getting.
The only reason this is sort of not making my head explode is that I could see the input, and I could just set the list explicitly, but if the length was unknown it would be an issue
CodePudding user response:
When you use *
, Python creates a list where each element references the same object. Thus, modifying one element ends up modifying all of them.
arr = [{0:0, 1:0}] * 12 # this creates a list where every element is the same dictionary
arr = [{0:0, 1:0} for _ in range(12)] # this creates a list containing 12 independent dictionaries