问题
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:
x_hist property is static class property
variables Declared inside classes are static variables different from the context of instance which means,
>>> s = M()
>>> s
<__main__.M object at 0x7f9ffb4a6358>
>>> s.i
3
>>> M.i
3
>>> s.i = 4
>>> M.i
3
>>> s.i
4
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)
For static Method and ClassMethod check Here
For Nice Tutorial for Classes Refer Here
回答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.
来源:https://stackoverflow.com/questions/54983763/appending-values-to-an-array-within-an-object-looping-over-objects