1

I have the following code, and I simply want it to write the list to a file. It does so, but with a blank line each time, which causes problems with every iteration!

with open("films.txt", mode='r') as f:
 allfilms=[]

 reader = csv.reader(f)
 for row in reader:
    #create a list again which reads in and stores all films in the file

    allfilms.append(row)
    print(allfilms)


with open("films.txt","w") as f:
     writer=csv.writer(f)
     writer.writerows(allfilms)

The output is: 0,Genre, Title, Rating, Likes

    1,Sci-Fi,Out of the Silent Planet, PG, 0

    2,Sci-Fi,Solaris, PG,0

    3,Sci-Fi,Star Trek, PG, 0

    4,Sci-Fi,Cosmos, PG, 0

As mentioned, I don't want the blank line when saving the list. Also, I'd be interested in more elegant or better ways of doing the same thing. I want the file to be READ in to the list, and then written back to the file EXACTLY the same, in terms of formatting, as what was stored in the file.

Thanks in advance

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
  • 4
    try using `allfilms.append(row.strip('\n')` – chickity china chinese chicken Jan 27 '17 at 00:03
  • 1
    Which version of Python are you using? In Python 2, the CSV module expects files to be opened in binary mode. In Python 3, you need the output file to be opened with the parameter `newline=""` for it to work correctly. – Blckknght Jan 27 '17 at 02:00
  • @downshift - actually the following error occurs on using what you suggested: AttributeError: 'list' object has no attribute 'strip' –  Jan 27 '17 at 12:04

2 Answers2

10

I believe the source of your issue is that when you opened films.txt, you forgot to include the newline='' argument as the docs say to use. This means your code becomes:

with open("films.txt", mode='r', newline='') as f:

and

with open("films.txt", mode='w', newline='') as f:
BluCode
  • 1,097
  • 7
  • 16
2

Edit: I misunderstood how the csv module gave output when I wrote this answer, but I am not removing it due to the helpful comment by downshift on it. Please see my more recent and more accurate answer.

downshift answered this in the comments, but I will try to give a little more detail about why this is happening.

When you read each row in from the csv reader, it gives you the entire row, which includes the newline character (\n) at the end. Your issue stems from the fact that when you write to the file, the write function adds it's own newline character to the end of your string. Luckily there are two very simple ways to remove the newline character from the end of the line you get back from the csv reader.

One way is to use the .strip() method of a string, which takes in some characters in the form of a string as input, and strips of as many of those characters as possible from the ends of the string. Using this method you could replace:

allfilms.append(row)

with

allfilms.append(row.strip("\n"))

Another way you could do it is to use string slicing and slice off the last character of the string. I wouldn't recommend you use string slicing for this, because it is less clear what you are doing, but if you wanted to, you would replace:

allfilms.append(row)

with

allfilms.append(row[:-1])

row[:-1] will return row with the last character excluded, discarding the newline character.

Hope this helped you!

BluCode
  • 1,097
  • 7
  • 16
  • Very helpful explanation, thank you. However, AttributeError: 'list' object has no attribute 'strip' ....is the error message that occurs on using what you suggested with the row.strip("\n")). Having said that, your second suggestion BlueCode, worked! So, thanks –  Jan 27 '17 at 12:06
  • Interestingly allfilms[3] produces the third row in the list. I need to know however, how to get at the fourth field in the third row, if that makes any sense. I tried allfilms[3][4], but it came up with the error:"List index out of range". Any thoughts? –  Jan 27 '17 at 12:09
  • 1
    @pythoncarrot, just offering my thoughts until BluCode can respond. Lists in python are typically zero-indexed (meaning they start from zero for the first element), so a list index out of range suggests the index is higher than what is available..meaning `allfilms[2][3]` should point to the 3rd row, 4rd index. Consider trying that to get around that error. – chickity china chinese chicken Jan 27 '17 at 18:02