list.append() does not appear to work correctly

I have created a python function, which should take a series of 3D co-ordinates and place them in a list (within a list).

However when I print out coord_list, it doesn't appear to append correctly, for example when these co-ordinates are entered :

[1,2,3]

[2,3,4]

[3,4,5]

The output of coord_list finally (ignoring the 'q') will be: [[3,4,5],[3,4,5],[3,4,5]].

Why does it not append correctly, and how can this be fixed?

def coords() :

    xyz_list = []
    coord_list = []

    while 1 :
        xyz = raw_input("Enter co-ordinates (x,y,z) enter 'q' when done: ")
        xyz = str(xyz)

        del xyz_list[:]

        for num in xyz.split(","):
            xyz_list.append(num)

        print xyz_list

        if xyz[0] != 'q' :
            coord_list.append(xyz_list)
            print coord_list
        else :
            break

coords()

This is because coord_list is storing [xyz_list, xyz_list, ...]. You are updating xyz_list in each iteration which is in turn being updated in coord_list.


The problem lies in the del which accesses the managed heap. New objects (the members of xyz_list) appear on the same spot because the containing list is not deleted. So the list members replace the previous ones in-place and the reference in coord_list will point to the new values.

Reproduction in python 2.7.9 (Linux):

$ python coords.py

Enter co-ordinates (x,y,z) enter 'q' when done: 1,2,3
['1', '2', '3']
[['1', '2', '3']]
Enter co-ordinates (x,y,z) enter 'q' when done: 2,3,4
['2', '3', '4']
[['2', '3', '4'], ['2', '3', '4']]
Enter co-ordinates (x,y,z) enter 'q' when done: 3,4,5
['3', '4', '5']
[['3', '4', '5'], ['3', '4', '5'], ['3', '4', '5']]

I made a small change to the script: del xyz_list[:] --> xyz_list = [].

Now it works:

$ python coords.py

Enter co-ordinates (x,y,z) enter 'q' when done: 1,2,3
['1', '2', '3']
[['1', '2', '3']]
Enter co-ordinates (x,y,z) enter 'q' when done: 2,3,4
['2', '3', '4']
[['1', '2', '3'], ['2', '3', '4']]
Enter co-ordinates (x,y,z) enter 'q' when done: 3,4,5
['3', '4', '5']
[['1', '2', '3'], ['2', '3', '4'], ['3', '4', '5']]

Remove del and clear the list xyz_list after adding it to coord_list:

def coords() :

    xyz_list = []
    coord_list = []

    while 1 :
        xyz = raw_input("Enter co-ordinates (x,y,z) enter 'q' when done: ")
        xyz = str(xyz)

        for num in xyz.split(","):
            xyz_list.append(num)

        print xyz_list

        if xyz[0] != 'q' :
            coord_list.append(xyz_list)
            print coord_list
            xyz_list = []
        else :
            break

coords()

Output:

Enter co-ordinates (x,y,z) enter 'q' when done: 1,2,3
['1', '2', '3']
[['1', '2', '3']]
Enter co-ordinates (x,y,z) enter 'q' when done: 4,5,6
['4', '5', '6']
[['1', '2', '3'], ['4', '5', '6']]