469,362 Members | 2,548 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,362 developers. It's quick & easy.

Help - strange behaviour from python list


I've managed to create a scenario in which editing an object in a list of
objects seems to edit every object in the list, rather than just the one.
I'm totally stumped and wondered if anyone would be kind enough to read my
explanation and see if they have any suggestions. I have probably stumbled
into some typical newbie problem, but anyway:

I have two classes, Area and Agent:

class Agent:
def __init__(self,name):
self.name = name

class Area:
def __init__(self, occupants = []):
self.occupants = occupants

Now, I want to create a 'virtual environment' as a 2D list of Area
objects, so:

environment = []
for x in range(0,10):
environment.append([])
for y in range(0,10):
new_area = Area()
environment[-1].append(new_area)

This works fine, environment is now a 10*10 2D list of Area objects, and
the occupants member of each Area object is [].

Now, I want to add an occupants, in the form of an Agent object, to an
area in the environment:

new_agent = Agent("Bob")
environment[4][5].occupants.append(new_agent)

This is where it goes wrong, it looks as if new_agent gets appended to the
occupants list of EVERY Area object in environment. For example, the
following code:

for areas_list in environment:
for area in areas_list:
print len(area.occupants)

Will print out `1` 100 times over.

I must be making some really stupid mistake, but this just doesn't look
like the list behaviour I would expect. What's going on here?
--
Apr 11 '06 #1
4 1058
Sean Hammond schrieb:

I've managed to create a scenario in which editing an object in a list
of objects seems to edit every object in the list, rather than just the
one. I'm totally stumped and wondered if anyone would be kind enough to
read my explanation and see if they have any suggestions. I have
probably stumbled into some typical newbie problem, but anyway:


just a hint
def foo(val,lst=[]): .... lst.append(val)
.... print lst
....

foo(1) [1] foo(2) [1, 2] foo(3) [1, 2, 3] foo(4,[0]) [0, 4]
here list lst is created and bound once
compare with this one (which is what you really want)
def bar(val, lst=None): .... if lst is None:
.... lst = []
.... lst.append(val)
.... print lst
.... bar(1) [1] bar(2) [2] bar(3, [0]) [0, 3]


hth, Daniel
Apr 11 '06 #2
Sean Hammond wrote:
class Area:
def __init__(self, occupants = []):
self.occupants = occupants
.... I must be making some really stupid mistake, but this just doesn't
look like the list behaviour I would expect. What's going on here?


Whenever you use the default value for occupants in the constructor you
reuse the same list. Don't use mutable objects as default values:

def __init__(self, occupants=None):
if occupants is None:
self.occupants = []
else:
self.occupants = occupants
Apr 11 '06 #3
Sean Hammond wrote:
I've managed to create a scenario in which editing an object in a list of
objects seems to edit every object in the list, rather than just the one.
I'm totally stumped and wondered if anyone would be kind enough to read my
explanation and see if they have any suggestions. I have probably stumbled
into some typical newbie problem, but anyway:


some useful resources:

http://docs.python.org/tut/node6.htm...00000000000000
(see the paragraph that starts with "important warning")

http://www.python.org/doc/faq/genera...etween-objects

http://docs.python.org/ref/function.html
(see the paragraph that starts with "Default parameters are evaluated when the
function definition is executed")

(you cannot say we didn't warn you ;-)

</F>

Apr 11 '06 #4

Right, thanks everyone, that's a useful lesson learned. As I suspected I
was being tripped over by some feature of Python I was unaware of. I had
been looking up lists in the documentation, not functions, and could find
no explanation.

Prbolem solved!

--
Apr 11 '06 #5

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

4 posts views Thread by Ben | last post: by
2 posts views Thread by Markus Franz | last post: by
5 posts views Thread by Wolfgang.Stoecher | last post: by
24 posts views Thread by brian.bird | last post: by
13 posts views Thread by na1paj | last post: by
10 posts views Thread by conor.robinson | last post: by
9 posts views Thread by abcd | last post: by
8 posts views Thread by matthewperpick | last post: by
8 posts views Thread by Dox33 | last post: by
1 post views Thread by CARIGAR | last post: by
reply views Thread by suresh191 | last post: by
1 post views Thread by Marylou17 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.