Reputation: 434
Here is the problem. I have names.txt file. The contents of this file as follows. The question asks to display to numbers of names in this file. I could do with while loop. It works, no problem. But for some reason, if I wanted to do this with for loop it gives me wrong number of names.
Julia Roberts
Michael Scott
Kevin Malone
Jim Halpert
Pam Halpert
Dwight Schrute
This is the while loop. It runs perfect.
def main():
try:
# open the names.txt file in read mode.
infile=open("names.txt", "r")
# set an accumulator for number of names
numbers_of_name=0.0
# read the first line
line=infile.readline()
# read the rest of the file
while line!="":
numbers_of_name+=1
line=infile.readline()
# print the numbers of names in the names.txt file.
print("There are", int(numbers_of_name), "names in the names.txt file.")
# close the file
infile.close()
except IOError as err:
print (err)
# call the main function
main()
The console gives me correct answer.
There are 6 names in the names.txt file.
And this is my problematic for loop
def main():
try:
# open the names.txt file in read mode.
infile=open("names.txt", "r")
# set an accumulator for number of names
numbers_of_name=0.0
# read the rest of the file
for line in infile:
line=infile.readline()
numbers_of_name+=1
# print the numbers of names in the names.txt file.
print("There are ", numbers_of_name, "names in the names.txt file.")
# close the file
infile.close()
except IOError as err:
print (err)
# call the main function
main()
And this is the output.
There are 3.0 names in the names.txt file.
There should be 6 names not 3 names.:
What might be missing part in this file reading code? Thanks in advance.
Upvotes: 1
Views: 5184
Reputation: 10622
# Initialise count
count = 0
with open('bar.py', 'r') as fd:
# Strip newline char and and any leading/trailing spaces
lines = map(lambda x: x.strip(), fd.readlines())
# Strip empty lines
lines = filter(lambda x: x, lines)
# Get the count
count = len(lines)
print "Count: ", count
Note: With map and filter being used, we're iterating over the list twice. An efficient implementation (for a large list) would be to iterate over the elements just once and apply conditions to eliminate unwanted entries - empty lines, lines starting with #, etc.
Upvotes: 2
Reputation: 3211
The problem lies with this section
# read the rest of the file
for line in infile:
line=infile.readline()
numbers_of_name+=1
If you do a sectional print, you will see why:
# read the rest of the file
for i, line in enumerate(infile):
print (i, line)
line=infile.readline()
print (i, line)
numbers_of_name+=1
By doing line=infile.readline()
, you are changing the value of line
in the for
loop and altering it for subsequent loop passthrough
Upvotes: 2
Reputation: 1058
This one line will achieve what you're trying to do with all that code:
len(open("names.txt", "r").readlines())
A loop is not required for the purpose of counting the number of lines.
Upvotes: 1
Reputation: 1196
The problem is you are reading two lines in each iteration, when you do:
for line in infile:
line is the first line in the file, when you do:
line.readline()
Then line is now the second line, and then you add one two you name count
You should do:
for line in infile:
numbers_of_name+=1
Upvotes: 6