0

I'm new in python language and I'm trying to handle a csv file with this very simple test code:

import csv
csvfile= str(input("write file input name\n"))
read_file = open(csvfile)
file_in = csv.reader(read_file, delimiter=' ')
print("number of rows of",csvfile,"is:",len(list(file_in)))
i=1
for var in file_in :
    if i>1:
        print(var[1])
    i +=1
print("number of rows of",csvfile,"is:",len(list(file_in)))

giving this code a simple file "letters.csv" containing 7 rows like this:

a 2
b 7
c 9
d 11
e 3
f 9
g 96

what's strange for me is:

  1. why this code enter the for-loop and returns what I want only if I comment line 5 (print("number...)? Uncommenting line 5 the output is:
write file input name
letters.csv
number of rows of letters.csv is: 7
number of rows of letters.csv is: 0

commenting line 5 the output is:

write file input name
letters.csv
7
9
11
3
9
96
number of rows of letters.csv is: 0
  1. Why the expression in the last line (equal to line 5) returns always 0? Shouldn't be 7?
1
  • You're consuming the csv reader by converting it to a list. Commented Jun 17, 2021 at 10:28

3 Answers 3

1

file_in can only be iterated once. Your are trying to iterate it twice, the first time when you convert it to a list with list(file_in) and the second time when you execute the loop beginning for var in file_in :.

This can be corrected and a couple of improvements can be made. See the comments I have added to the code below. You should also study the PEP 8 -- Style Guide for Python Code:

import csv
#csvfile= str(input("write file input name\n"))
csvfile= input("write file input name\n") # the result of input is already a string
read_file = open(csvfile, newline='') # add newline argument
file_in = csv.reader(read_file, delimiter=' ')
print("number of rows of",csvfile,"is:",len(list(file_in)))
i=1
read_file.seek(0, 0) # position file back to the beginning
file_in = csv.reader(read_file, delimiter=' ') # create new iterator
i=0
for var in file_in :
    print(var)
    i +=1
print("number of rows of",csvfile,"is:", i)
close(read_file) # You should close your files
Sign up to request clarification or add additional context in comments.

Comments

1

See the Python docs for the csv library reader function.

Return a reader object which will iterate over lines in the given csvfile.

You are exhausting the reader object in line 5 with list(file_in).

If you must find the length of the file before iterating through the reader object, you can produce a list first. Note that this will put the whole file into memory which becomes unwise when the csv file is very large.

import csv
csvfile = str(input("write file input name\n"))
read_file = open(csvfile)
file_in = csv.reader(read_file, delimiter=' ')
file_lines = list(file_in)
print("number of rows of", csvfile, "is:", len(file_lines))
i = 0
for line in file_lines:
    if i > 0:
        print(line[1])
    i += 1

Comments

0

That's because file_in is a kind of iterator. When you read it in the for loop, you pop the lines one after the other.

Solution : don't use len(file_in) to get the length after a loop in it. Instead, make a list with datas or trust only file_in before looping in it

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.