Python Over-writing My List Elements
Solution 1:
I think it is worth noting that if you have more than 1 galaxy, they'll share the same stars. This could lead you to believe that you're overwriting your stars when you really aren't...
I'm guessing you would probably be better with an __init__
that looks like:
def__init__(self,numin,xes,vees,masses):
self.stars = []
self.numstars = numin
for n inrange(numin):
self.stars.append(Star(xes[n],vees[n],masses[n]))
Here I've shifted the class attributestars
to be an instance attribute. Now each instance will have it's own stars
list instead of sharing one stars
list with all of the other galaxies in the universe.
As others have noted, your history
list is going to suffer from a similar problem (You have multiple references to the same list). However, the fix really depends on what you do in self.velstep
and self.xstep
. If you modify the Star
objects in place, then a simple (shallow) list copy won't do you any good (e.g. gal.time_stepper(0.1)[:]
). (You'll create a new list, but it will hold the same stars which are constantly being updated). In that case, you'll want copy.deepcopy
when you append to your history list:
history=[]
for n in range(100):
history.append(copy.deepcopy(gal.time_stepper(.1)))
Solution 2:
This is because the stars
list is mutable - it is a changeable variable. When you call stars.append
, it does not create a new list - it simple edits the existing list. And when you call history.append(x)
, python does not create a fresh, clean copy of x
- it assumes you want the "real" x
to be placed in the history
array.
If you'd like to copy the state of the list at each iteration, there are several options (see How to clone a list in python?).
The copy
module will do the trick. It offers both 'shallow' and 'deep' copies - roughly speaking, deep copies attempt to also copy any other variables they find inside an object (for example, lists containing other lists), while shallow ones just go one layer down:
Here's shallow copies with copy
:
importcopy
history=[]
for n in range(100):
history.append(copy.copy(gal.time_stepper(.1)))
And deep copies:
importcopy
history=[]
for n in range(100):
history.append(copy.deepcopy(gal.time_stepper(.1)))
Slicing the array will work, since it always shallow copies as an intermediate step:
history = []
for n in range(100):
history.append(gal.time_stepper(.1)[:])
You can also call list
on the existing list - this typecast-esque operation always returns a new list object (again, shallowly):
history = []
for n in range(100):
history.append(list(gal.time_stepper(.1)))
Solution 3:
It is not changing or over writing all of the values, but rather all of the elements in the history point to the same array object. You need to assign by value as opposed to reference by using a copy of the array.
Post a Comment for "Python Over-writing My List Elements"