make a change to an element within a list within a list
i am reading a csv file into a data:
def get_file(start_file): #opens original file, reads it to array
with o开发者_JS百科pen(start_file,'rb') as f:
data=list(csv.reader(f))
i need to go through every row and add a value to row[1] like this. initially row[1] = 'Peanut'
, i need to add 'Butter' so the result would be
row[1]='PeanutButter'
i need to do this for every row like this
for row in data:
row+='Butter'
is this the correct way of doing it?
You want
for row in data:
row[ 1 ] += "Butter"
but the right way to do this is not to iterate through every row of data
again but to modify the way you generate data
in the first place. Go look at my answer in your other question.
Copy-paste from your previous question
def get_file( start_file )
f = csv.reader( start_file )
def data( csvfile ):
for line in csvfile:
line[ 1 ] += "butter"
yield line
return data( f )
which you use like
lines = get_file( "my_file.csv" )
for line in lines:
# do stuff
Explanation
The issue here is that we want to modify the data held in data
. We could look through and change every element in data
, but that's slow, especially given that we're going to look through every element again shortly. Instead, a much nicer way is to change the lines as they are inserted into the data holder, because that saves you one pass.
Here goes:
f = csv.reader( start_file )
I have modified the code to use csv.reader
, because that's a much more robust way of reading CSV data. It's basically a trivial change; it works like open
but each line is a tuple of the values, already separated for you.
def data( csvfile )
This is different! Instead of making data a variable, we're making it a function. That doesn't sound right, but bear with me.
for line in csvfile:
OK, data
is a function of csvfile
so we're just iterating through the lines in the first argument. So far, so good.
line[ 1 ] += butter
This is the change you wanted to make: we add "butter" to the second element of line
. You could also make other changes here: add a column to each row, delete columns, skip rows, the list goes on!
yield line
This is clever Python trickery. It basically works like return
, but without stopping the function from running. Instead, it is paused until we ask for the next value.
So now data
is a function which returns each of the lines (modified just as you wanted them) in turn. What now? Easy:
return data( f )
Make get_file
return data
!
What does this mean? Well, we can now use it as the iterable in a for loop:
for line in get_file( "my_file.csv" ):
and everything will work!!! Magic!! =p
A couple of other points:
Previously, you used
with ... as ...
syntax. This is acontext manager
: it automatically closes the file when you're done with it. But in this case we don't want to do that, since we are reading lines from the file as we go through. Casting it to alist
copies the whole thing into memory, which is sloooooow. You should add f.close() elsewhere in the code if you're worried about memory leaks.I had another point, but I can't remember it...
for flist in data:
for element in flist:
element += 'butter'
Is that what you want?
精彩评论