Appending values to an array within an object (loo

2019-08-28 14:56发布

问题:

This is an uncluttered version of this question. Since I changed so much I made a new question

I am trying to take certain values from a longer array solution and put them into a smaller array, within an object. This code is supposed to take the first half of the solution array and put it into x_hist within m1, and the second half of the solution array and put it into x_hist within m2. Instead it appears to take all of the solution array and put it into x_hist for both objects. Anyone know why this may be the case? Have I accidentally vectorized the code?

class Mass:
    x_hist = []

m1 = Mass()
m2 = Mass()
ms = [m1,m2]

solution = [1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, 0, 0, 0, 0, 0]

for i in range(len(ms)):
    for k in range(int(len(sol)/len(ms))):
        ms[i].x_hist.append(solution[k+8*i])

print(m1.x_hist)
print(m2.x_hist)

The output is:

[1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, 0, 0, 0, 0, 0]
[1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, 0, 0, 0, 0, 0]

I am trying to get an output of:

[1, 2, 3, 4, 5, 6, 7, 8]
[0, 0, 0, 0, 0, 0, 0, 0]

回答1:

because your x_hist property is static class property shared by all classes

class Mass:
    #x_hist = [] shared by all classes its static
    def __init__(self):
        self.x_hist = []

m1 = Mass()
m2 = Mass()
ms = [m1,m2]

solution = [1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, 0, 0, 0, 0, 0]

for i in range(len(ms)):
    for k in range(int(len(sol)/len(ms))):
        ms[i].x_hist.append(solution[k+8*i])

print(m1.x_hist)
print(m2.x_hist)


回答2:

I suspected the following was the case, but I don't fully understand yet. Essentially, your class construction is not correct: x_hist was never declared as an attribute of the Mass() class. So it was just appending to (I assume) the globally declared x_hist.

class Mass():
    def __init__(self):
        self.x_hist = []

m1 = Mass()
m2 = Mass()
ms = [m1, m2]

solution = [1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, 0, 0, 0, 0, 0]

for i in range(len(ms)):
    for k in range(int(len(solution)/len(ms))):
        ms[i].x_hist.append(solution[k+8*i])

print(m1.x_hist)
print(m2.x_hist)

Returns:

[1, 2, 3, 4, 5, 6, 7, 8]
[0, 0, 0, 0, 0, 0, 0, 0]


回答3:

The problem is basically in the nested loops! once the first iteration of the outer loop is done, you restart the inner loop so you basically append the first half in both lists.

It's better to rewrite the loops, for readability:

step = int(len(solution)/len(ms))
for m, k in zip(ms, range(0,len(solution), step)):
    m.x_hist.extend(solution[k : k+step])
print(m1.x_hist)
print(m2.x_hist)
[1, 2, 3, 4, 5, 6, 7, 8]
[0, 0, 0, 0, 0, 0, 0, 0]

EDIT:

The class attribute shared by all instances mentioned above can be accessed by:

Mass.x_hist

And this will contain all solution elements. If you simply try to access the x_hist of an instance, you are correct to access through m1.x_hist but you should probably not use class variables unless necessary.