mululu
mululu

Reputation: 411

list of objects containing lists of objects

I'm trying to create a list of objects (Elements), where each element contains a list of objects (GaussPoints). The number of GaussPoints per Element can be variable, although in the example below each element has only one GaussPoint for simplicity.

class Element:
    gp = []

class GaussPoint:
    argument = 0


k = 0
elements = []
for ele in xrange(4):
    k = k+1
    anEle = Element()

    aGP = GaussPoint()
    aGP.argument = k
    print k

    elements.append(anEle)

    elements[ele].gp.append(aGP)

print "testing the data structure:"
for ele in xrange(4):
    print elements[ele].gp[0].argument

The output is:

1
2
3
4
testing the data structure:
1
1
1
1

What I'm expecting would be:

1
2
3
4
testing the data structure:
1
2
3
4

Somehow the code doesn't create a new list of GaussPoints for each Element, but appends to the same one.

I'm obviously misunderstanding something quite fundamental about Python. Could anyone please help?

Upvotes: 0

Views: 216

Answers (2)

NPE
NPE

Reputation: 500475

You need to make Element.gp an instance variable, like so:

class Element:
    def __init__(self):
        self.gp = []

Currently, gp is a member of the class itself and is in effect shared by all instances of the class. You change it in one, and it appears to change in all.

It is arguably good style to make the same change to GaussPoint.argument:

class GaussPoint:
    def __init__(self):
        self.argument = 0

Finally, I'd recommend reading the tutorial on classes.

Upvotes: 3

jbowes
jbowes

Reputation: 4150

You're initializing Element.gp as a class variable, rather than an instance variable, so it's shared across all your Element objects. You end up with 1 gp being an array of length 4, rather than 4 gps of length 1.

Instead, initialize it in an __init__ method like so:

class Element:
    def __init__(self):
        self.gp = []

You're making argument a class variable, but since you reassign it for each instance, rather than modify it as you do element, it ends up holding the value you'd expect.

Upvotes: 2

Related Questions