Appending values to an array within an object (looping over objects)

纵然是瞬间 提交于 2019-12-24 20:14:57

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!