3

This is my csv file named 'test.csv':

aaa,,
ccc,ddd,
,eee,

And this is my code:

import csv

with open('test.csv', 'rt') as f:
  a = list(csv.reader(f))
  r = a[:]

for row in r:
    for index in range(3):
      if row[index] == '':
        row[index] = 'xxx'

print(r)
print(a)

The result:

[['aaa','xxx','xxx'],['ccc','ddd','xxx'],['xxx','eee','xxx]]
[['aaa','xxx','xxx'],['ccc','ddd','xxx'],['xxx','eee','xxx]]

I only want to change the content in list 'r', but why the list 'a' didn't remain the original one [['aaa','',''],['ccc','ddd',''],['','eee','']]?

3 Answers 3

2

The reason this is happening is that the same reference to the internal lists is being maintained. Lets take this as integers instead: If you have the list a = [1, 2, 3] you would expect b to also be [1, 2, 3] when you do b = a[:]. This is the case with your example. The list stores pointers to the other lists. If you just copy the list you will get those same pointers and be modifying the same underlying list as show below:

In [14]: a = [[1,2,3],[4,5,6],[7,8,9]]
In [15]: b = a[:]
In [16]: id(a)
Out[16]: 4499634512
In [17]: id(b)
Out[17]: 4499967296
In [18]: id(a[0])
Out[18]: 4499909664
In [19]: id(b[0])
Out[19]: 4499909664

Note that while id(a) and id(b) are different, id(a[0]) and id(b[0]) are the same. Doing b = a[:] creates a shallow copy of the list. You need to make a deep copy. This can be done with the deepcopy function of the copy library.

In [20]: from copy import deepcopy
In [21]: c = deepcopy(a)
In [22]: id(c[0])
Out[22]: 4500008112
In [23]: id(a[0])
Out[23]: 4499909664
In [24]: a[0][0] = 42
In [25]: a
Out[25]: [[42, 2, 3], [4, 5, 6], [7, 8, 9]]
In [26]: c
Out[26]: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

Hope this helps!

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

Comments

0

Well in that case you need to deep copy the list. r = a[:] does not do a deep copy. Try:

import copy;
r = copy.deepcopy(a[:])

Comments

0

Because a is a list of lists, where the outer list is the rows and the inner lists are the columns within each row. Doing a[:] makes a copy of the outer list, but each element within that copied list is still a reference to the original inner list.

You should use copy.deepcopy instead.

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.