2

Here is my code -

cumulative_nodes_found_list = []
cumulative_nodes_found_total_list = []

no_of_runs = 10

count = 0

while count < no_of_runs:

 #My program code

 print 'cumulative_nodes_found_list - ' + str(cumulative_nodes_found_list)
 cumulative_nodes_found_total_list.insert(count,cumulative_nodes_found_list)
 print 'cumulative_nodes_found_total_list - ' + str(cumulative_nodes_found_total_list)
 count = count + 1

Here is a part of the output -

#count = 0
cumulative_nodes_found_list - [0.0, 0.4693999, 0.6482, 0.6927999999, 0.7208999999, 0.7561999999, 0.783399999, 0.813999999, 0.8300999999, 0.8498, 0.8621999999]

cumulative_nodes_found_total_list - [[0.0, 0.4693999, 0.6482, 0.6927999999, 0.7208999999, 0.7561999999, 0.783399999, 0.813999999, 0.8300999999, 0.8498, 0.8621999999]]

#count = 1
cumulative_nodes_found_list - [0.0, 0.55979999999999996, 0.66220000000000001, 0.69479999999999997, 0.72040000000000004, 0.75380000000000003, 0.77629999999999999, 0.79679999999999995, 0.82979999999999998, 0.84850000000000003, 0.85760000000000003]

cumulative_nodes_found_total_list -[[0.0, 0.55979999999999996, 0.66220000000000001, 0.69479999999999997, 0.72040000000000004, 0.75380000000000003, 0.77629999999999999, 0.79679999999999995, 0.82979999999999998, 0.84850000000000003, 0.85760000000000003], 
[0.0, 0.55979999999999996, 0.66220000000000001, 0.69479999999999997, 0.72040000000000004, 0.75380000000000003, 0.77629999999999999, 0.79679999999999995, 0.82979999999999998, 0.84850000000000003, 0.85760000000000003]]

As the new item is appended the old item is replaced by new item. This trend continues. Can anyone tell me why this is happening. I have tried using 'append' in place of insert but got the same output. However when I use 'extend' I get the correct output but I need inner items as lists which I dont get with extend.

6
  • Is your question "What is the bug in #My program code"? Commented Jan 31, 2010 at 11:58
  • Yes that is the question Commented Jan 31, 2010 at 11:59
  • 3
    Only Jon Skeet can tell you what the bug is without actually knowing what the code does. Commented Jan 31, 2010 at 12:00
  • What is the expected/desired output? Commented Jan 31, 2010 at 12:05
  • -1: No useful code. -1: No expected results. Commented Jan 31, 2010 at 12:52

9 Answers 9

6

You need to rebind cumulative_nodes_found_list at the beginning of the loop, instead of just clearing it.

Sign up to request clarification or add additional context in comments.

5 Comments

Psychic debugging at its best.
How do I rebind the cumulative_nodes_found_list? Yes I am just clearing it at the moment after each iteration.
cumulative_nodes_found_list = []
@Lasse: I prefer the term "forensic debugging". All you have is a murder scene, and you have to figure out where the code went bad.
Oooh, much better term, thanks! Now I feel like a CSI :D "Code Scene Investigator"? Better word than Scene for the S? :)
2

This is psychic debugging at its best, since you're effectively asking "what is wrong with my code, which I'm not going to show to you".

All I can do is assume.

I'm assuming you're re-using the array objects in memory.

In other words, you do something like this:

list1.insert(0, list2)
list2.clear()
list2.append(10)
list2.append(15)
list1.insert(0, list2)

Since list1 points to the same array/list the whole time, and you're adding a reference to the object, and not a copy of it, later changes will make it appear your copy changed.

In other words, the result of the code above is going to be:

[[10, 15], [10, 15]]

regardless of what was in the list before you added it the first time.

Try assigning the changing list a new, empty, object each time you enter the loop body and see if that fixes anything.

Comments

1

You are adding a reference to cumulative_nodes_found_list to the cumulative_nodes_found_total_list, but it's the same reference each time. Move this line into the loop body:

cumulative_nodes_found_list = []

Comments

1

Lists are mutable objects. You're mutating cumulative_nodes_found_list inside your code, so the object added to your total list in the previous run is also mutated, because they are the same object.

Either make a copy to insert in the total:

for count in xrange(no_of_runs):
   # ...
   cumulative_nodes_found_total_list.append(list(cumulative_nodes_found_list))

... or reset the list on each iteration:

for count in xrange(no_of_runs):
   cumulative_nodes_found_list = [] # creates a NEW list for this iteration
   # ...
   cumulative_nodes_found_total_list.append(cumulative_nodes_found_list)

Comments

1

I believe the problem is in the rest of your program code. The items in cummulative_nodes_found_list is being replaced in-place each time through the loop.

I assume you're doing something like this:

while count < no_of_runs:
    cummulative_nodes_found_list.clear()
    #fill up the list with values using whatever program logic you have
    cummulative_nodes_found_list.append(1.1)
    cummulative_nodes_found_list.append(2.1)
    print 'cumulative_nodes_found_list - ' + str(cumulative_nodes_found_list)
    cumulative_nodes_found_total_list.insert(count,cumulative_nodes_found_list)
    print 'cumulative_nodes_found_total_list - ' + str(cumulative_nodes_found_total_list)
    count = count + 1

if this is, infact, what you're doing, then instead of using 'clear()' to clear the list, create a new one:

ie, replace cummulative_nodes_found_list.clear() with

 cummulative_nodes_found_list = []

Comments

1

My guess is that you are not assigning the cumulative_nodes_found_list to be a new list each time, but updating its contents instead. So each time around the loop you are adding the same list reference to the total list. Since the reference within the totals list is the same object, when you update this list the next time around the loop, it affects what you hoped was the last loops values.

Comments

0

If you want to append to a list, use mylist.append(item) instead.

Also, if you iterate a fixed number of times it's better to use a for loop:

for i in range(no_of_runs):
  # do stuff

The idea is, that range(no_of_runs) generates the list [0, 1, 2, ..., 10] for no_of_runs = 10 and the loop then iterates over its values.

Edit: this doesn't solve the problem. Other answers in this thread do, however. It's just a comment on style.

2 Comments

Use xrange if no_of_runs is very large; it uses a generator so it doesn't need to store the full list.
But only for Python 2.x, in Python 3 range() makes a generator. And better use xrange all the time for Python 2.x. :)
0

This method worked for me. Just like you, I was trying to append/insert a list into another list.

cumulative_nodes_found_total_list.insert(count,cumulative_nodes_found_list)

But the old values were being appended by the new values. So instead I tried this -

cumulative_nodes_found_total_list.insert(count,cumulative_nodes_found_list[:])

Comments

-1

"Assignment statements in Python do not copy objects, they create bindings between a target and an object."

Use deepcopy (or copy)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.