I have a class that has a list inside my constructor
class FCM:
def __init__(self, input_table, attributes, num_centroids, m, start_indep, pos_of_y):
    self.xs = # it's a list of lists
self.xs is a list of lists that gets passed to a function down below. I made a copy because I wanted to be certain that the xs did not change as a result of my function.
from copy import copy
    xs_copy=[]
    xs_copy=copy(self.xs)    
self.current_centroids=self.get_initial_centroids(xs_copy)   
And here is the function:
def get_initial_centroids(self, these_xs):
    print str(self.xs[0])               
    for i in range(len(these_xs)):
        these_xs[i].append(self.cluster_distance(these_xs[i][self.start_indep:], avg_centroid))
    print str(self.xs[0])    # Why is my class list affected???????
What I'd like to understand is why self.xs is affected at all by this function as I passed a copy of it to my function.
For those interested in more than just the gist:
from __future__ import division
import MySQLdb
class FCM:
    def __init__(self, input_table, attributes, num_centroids, m, start_indep, pos_of_y):
    self.input_table=input_table
    self.db=MySQLdb.connect()
    self.cursor=self.db.cursor()
    self.cursor.execute("select " + ",".join(attributes) + " from " + input_table)
    ys=[]
    for record in self.cursor.fetchall():
         ys.append([int(r) if type(r) is long else r for r in list(record)]) # some of the data is of type long and should be of type integer  
    self.xs=ys[:]
    self.num_centroids=num_centroids
    self.m=m        
    self.start_indep=start_indep
    self.pos_of_y=pos_of_y
    from copy import copy
    xs_copy=[]
    xs_copy=copy(self.xs)   
    self.current_centroids=self.get_initial_centroids(xs_copy)       
    print "Initial centroids are " + str(self.current_centroids)    
def get_initial_centroids(self, these_xs):
    running_total=these_xs[0][self.start_indep:]
    cnt=0
    for this_x in these_xs[1:]:
        running_total = self.vector_add(running_total, this_x[self.start_indep:])
        cnt += 1
    avg_centroid=self.scalar_mult(running_total, 1/cnt)   
    print str(self.xs[0]) # this is the same as in the constructor              
    for i in range(len(these_xs)):
        these_xs[i].append(self.cluster_distance(these_xs[i][self.start_indep:], avg_centroid))
    print str(self.xs[0])  # but now self.xs has changed
