Reputation: 23
Reading a csv, I find I'm unable to iterate through rows if there are any preceding statements in my with
block.
For example, if I do this:
with open (TargetFile) as source:
Strings = csv.reader(source)
for row in Strings:
print Strings.line_num
I'll get the integers 1 - (# of rows) printed to console. (Useless, yes, but I'm just testing the for
with something obvious.)
However, say I'm looking to grab a row at random. I'd want to first determine the # of rows and generate a random number within that range, then iterate through the rows in search of a matching line_num.
(Here, I've kept the useless print Strings.line_num
to avoid introducing new mistakes to the mix.)
with open (TargetFile) as source:
Strings = csv.reader(source)
CSV_Length = sum(1 for row in Strings)
print CSV_Length
RandRow = random.randrange(1,CSV_Length)
print RandRow
for row in Strings:
print Strings.line_num
#replace ^ with actually useful code
Will print the number of rows in the csv file and a random integer in that range to the console - all as expected - but the (previously working) for
loop won't be called. Without that loop, I can't get to the useful and interesting bit
What am I missing, here?
Upvotes: 2
Views: 46
Reputation: 10308
As Daniel said, the problem is that you are iterating over lines in the file. The proper solution, however, is to rewind the file:
Source.seek(0, 0)
This will put you back at the beginning of the file.
Upvotes: 0
Reputation: 599778
You're missing that Strings
is an iterator. Once you iterate it to get the length, it is exhausted. So the for loop now has nothing to operate on.
You could fix this by converting to a list straight away:
strings = list(csv.reader(source))
Having done this, you could now access len(strings)
to get the length anyway.
Upvotes: 1