Posts: 218
Threads: 89
Joined: Nov 2017
I’ve got a basic text file. I am trying to print the 5th line (total 7 lines).
Here is my text file:
Quote:Welcome to your First Tribulation Recruit.
Only the best recruits can become agents.
Do you have what it takes?
We will test your knowledge with this field readiness exam.
It should be pretty simple, since you only know the basics so far.
Let's get started.
Best of luck recruit.
Here is my code with some annotations for readability:
# Opening the file as a variable
with open('field.txt') as field_variable:
# Reading the file:
field_variable = field_variable.readlines()
# Turning it into a list:
list(field_variable)
# Splitting each line in the list:
for i in field_variable:
i.split()
# Printing third line from the bottom by reverse slicing:
print(field_variable[-3]) I am expecting this as the output:
Quote:It should be pretty simple, since you only know the basics so far.
That’s line 5.
And I actually do generate that output
Hooray! I won!
Ehm, not quite.
I wrote that code snippet myself but I only partially understand.
If you look at lines 8 and 9, how does the iterator (the ‘i’ aspect) in the for loop know to split each line? In my mind I’d figure that the the ‘i’ would go through every single individual character in the field_variable list. I don’t really understand this entirely.
Can someone here try to explain the logic of how the for loop knows to iterate through each line instead of each character?
Posts: 31
Threads: 0
Joined: Dec 2017
Aug-16-2018, 12:36 AM
(This post was last modified: Aug-16-2018, 12:37 AM by knackwurstbagel.)
In your code, i would contain a line in your file. Thus its a string, and the string method split() would take 'i' in this case and by default it would return a list where it splits the line on whitespace characters.
Make a minor change:
for i in field_variable:
print(i.split()) This will give you an idea of what split is doing here. In the end however you are printing the line correctly using a negative index of 3 in this case where you know its three lines from the bottom. Thus your for loop is not nessisary as your not using the output of i.split() in any way.
Posts: 12,019
Threads: 483
Joined: Sep 2016
you are doing something weird here. you use field_variable as a file pointer,
and then use it as your buffer. Not sure exactly how you get away with that, but expect it has to do with file buffering.
At any rate, it's not good.
here's how I would write that:
>>> from itertools import islice
>>> with open('field.txt') as fp:
... print(list(islice(fp, 4, 5)))
...
['It should be pretty simple, since you only know the basics so far.\n']
Posts: 218
Threads: 89
Joined: Nov 2017
Aug-16-2018, 01:18 AM
(This post was last modified: Aug-16-2018, 11:32 AM by Drone4four.)
This helps, @knackwurstbagel. My loop in its current form doesn’t actually do anything, as you’ve explained. But by modifying it slightly, also as you’ve suggested, it shows how the split function works. Here is the new output with your suggested modification:
Quote:['Welcome', 'to', 'your', 'First', 'Exam', 'Recruit.']
['Only', 'the', 'best', 'recruits', 'can', 'become', 'agents.']
['Do', 'you', 'have', 'what', 'it', 'takes?']
['We', 'will', 'test', 'your', 'knowledge', 'with', 'this', 'field', 'readiness', 'exam.']
['It', 'should', 'be', 'pretty', 'simple,', 'since', 'you', 'only', 'know', 'the', 'basics', 'so', 'far.']
["Let's", 'get', 'started.']
['Best', 'of', 'luck', 'recruit.']
It should be pretty simple, since you only know the basics so far.
I see now. The lines in the text file are split according to white space, not individual characters.
@Larz60+: Your code is elegant and far superior than mine. You mentioned buffering. I don’t really understand what you mean by file buffering and file pointers but it may have to do with the Jupyter Notebook tool that I’m doing this exercise with. You’ve done a terrific job re-writing my script on your own terms, but if I wanted to retain my somewhat novice approach while keeping my general awkward syntax, how would you modify my script to avoid making the mistake I made with the file-pointer buffer issue?
Posts: 1,950
Threads: 8
Joined: Jun 2018
Aug-16-2018, 04:39 AM
(This post was last modified: Aug-16-2018, 04:39 AM by perfringo.)
Another possible solution, without itertools:
>>> with open('field.txt', 'r') as quotes:
... for i, v in enumerate(quotes.readlines()):
... if i == 4:
... print(v)
... break # if line 5 reached you don't want iterate anymore
...
It should be pretty simple, since you only know the basics so far. I should be pretty much in line with your original syntax.
I'm not 'in'-sane. Indeed, I am so far 'out' of sane that you appear a tiny blip on the distant coast of sanity. Bucky Katt, Get Fuzzy
Da Bishop: There's a dead bishop on the landing. I don't know who keeps bringing them in here. ....but society is to blame.
Posts: 218
Threads: 89
Joined: Nov 2017
@perfringo: I really like your use of enumeration.
First you open the text file as a variable. Then for the two iterators inside the each line of the text file which you’ve declared, the first iterator, i , corresponds to each line. When i reaches line number 4, you print the other iterator, v . Then the operation is terminated.
A few days ago I was having difficulty grasping the concept of enumeration. There is a question on SO titled, “ What does enumerate mean?” which has quite a number of answers explaining enumeration in general. It all went over my head when I was reading it a few days ago. But your use of enumeration is clear and easily understood in the context of printing line 5 in my text file. Thank you for the clarification, @perfringo.
Posts: 7,310
Threads: 123
Joined: Sep 2016
Aug-16-2018, 03:10 PM
(This post was last modified: Aug-16-2018, 03:11 PM by snippsat.)
Just some point on @ perfringo enumerate solution,can drop readlines() make a list unnecessary and just iterate over file object.
Can also set index to 1 in enumerate,then it will count normal as usually is wanted in lines of a file.
with open('field.txt') as f_obj:
for index, line in enumerate(f_obj, 1):
if index == 5:
print(line.strip())
break Output: It should be pretty simple, since you only know the basics so far.
To not have break can make function.
def foo():
with open('field.txt') as f_obj:
for index, line in enumerate(f_obj, 1):
if index == 5:
return line.strip()
print(foo()) Output: It should be pretty simple, since you only know the basics so far.
|