Output using readlines in Python - python

I was wondering if anyone had an answer for this. In the image the top case has the code,
output of the two different lines of code from below:
def stats ():
inFile = open('textFile.txt', 'r')
line = inFile.readlines()
print(line[0])
and the second case has the code,
def stats ():
inFile = open('textFile.txt', 'r')
line = inFile.readlines()
print(line[0:1])
instead of going to the next iteration and printing it, it just spits out the iteration, now populated with all the \t and the end of line character \n. Can anyone explain why this is happening?

In the first case you're printing a single line, which is a string.
In the second case you're printing a slice of a list, which is also a list. The strings contained within the list use repr instead of str when printed, which changes the representation. You should loop through the list and print each string separately to fix this.
>>> s='a\tstring\n'
>>> print(str(s))
a string
>>> print(repr(s))
'a\tstring\n'
>>> print(s)
a string
>>> print([s])
['a\tstring\n']

Related

Read and convert row in text file into list of string

I have a text file data.txt that contains 2 rows of text.
first_row_1 first_row_2 first_row_3
second_row_1 second_row_2 second_row_3
I would like to read the second row of the text file and convert the contents into a list of string in python. The list should look like this;
txt_list_str=['second_row_1','second_row_2','second_row_3']
Here is my attempted code;
import csv
with open('data.txt', newline='') as f:
reader = csv.reader(f)
row1 = next(reader)
row2 = next(reader)
my_list = row2.split(" ")
I got the error AttributeError: 'list' object has no attribute 'split'
I am using python v3.
EDIT: Thanks for all the answers. I am sure all of them works. But can someone tell me what is wrong with my own attempted code? Thanks.
The reason your code doesn't work is you are trying to use split on a list, but it is meant to be used on a string. Therefore in your example you would use row2[0] to access the first element of the list.
my_list = row2[0].split(" ")
Alternatively, if you have access to the numpy library you can use loadtxt.
import numpy as np
f = np.loadtxt("data.txt", dtype=str, skiprows=1)
print (f)
# ['second_row_1' 'second_row_2' 'second_row_3']
The result of this is an array as opposed to a list. You could simply cast the array to a list if you require a list
print (list(f))
#['second_row_1', 'second_row_2', 'second_row_3']
Use read file method to open file.
E.g.
>>> fp = open('temp.txt')
Use file inbuilt generator to iterate lines by next method, and ignore first line.
>>> next(fp)
'first_row_1 first_row_2 first_row_3)\n'
Get second line in any variable.
>>> second_line = next(fp)
>>> second_line
'second_row_1 second_row_2 second_row_3'
Use Split string method to get items in list. split method take one or zero argument. if not given they split use white space for split.
>>> second_line.split()
['second_row_1', 'second_row_2', 'second_row_3']
And finally close the file.
fp.close()
Note: There are number of way to get respective output.
But you should attempt first as DavidG said in comment.
with open("file.txt", "r") as f:
next(f) # skipping first line; will work without this too
for line in f:
txt_list_str = line.split()
print(txt_list_str)
Output
['second_row_1', 'second_row_2', 'second_row_3']

List Index Out Of Range error when not out of range

I have a data file which only contains the following line:
"testA" "testB":1:"testC":2
Now when I split this line, and print the resulting list(w) I get the following:
['"testA"', '"testB":1:"testC":2']
[]
Now when I want to access w[0], it returns "testA" just fine, but when I print w[1], it crashes and gives a list index out of range error, but still prints it out "testB":1:"testC":2
Any help would be much appreciated!
Your code does not crash on w[1] on the "testA" "testB":1:"testC":2 line, otherwise it would not print "testB":1:"testC":2. Note the additional [] in your output? Your file contains some more empty lines, which are split to [], and which will then produce that error even on w[0].
To fix the problem, you should check whether the line and/or the list created from that line is non-empty. (When testing the line, make sure to strip away any whitespace, such as the trailing newline character.) Your code should then look somewhat like this:
with open("test.txt") as f:
for line in f:
if line.strip(): # strip the `\n` before checking whether line is empty
w = line.split()
print(w[0], w[1])
working for me without any error:
>>> a = '"testA" "testB":1:"testC":2'
>>> b = a.split(' ')
>>> b
['"testA"', '"testB":1:"testC":2']
>>> b[0]
'"testA"'
>>> b[1]
'"testB":1:"testC":2'
ae you doing anything different?
I also cannot reproduce your error but want to share a tip that I use in situations where I'm reading from a file and splitting on a delimiter.
cleaned_list = [ a.strip() for a in input_line.split(' ') if a ]
Simple and sanitizes the split list well.
The answer was that the program read the next line after the first one which it split, and that line was empty. So as soon as it tried to index the content of that (empty line) it crashed. That's why it DID print the first line, and then crashed. Thanks a lot for your help, though!

Trying to input data from a txt file in a list, then make a list, then assign values to the lines

allt = []
with open('towers1.txt','r') as f:
towers = [line.strip('\n') for line in f]
for i in towers:
allt.append(i.split('\t'))
print allt [0]
now i need help, im inputting this text
mw91 42.927 -72.84 2.8
yu9x 42.615 -72.58 2.3
HB90 42.382 -72.679 2.4
and when i output im getting
['mw91 42.927 -72.84 2.8']
where in my code and what functions can i use to define the 1st 2nd 3rd and 4th values in this list and all the ones below that will output, im trying
allt[0][2] or
allt[i][2]
but that dosent give me -72.84, its an error, then other times it goes list has no attribute split
update, maybe i need to use enumerate?? i need to make sure though the middle 2 values im imputing though can be used and numbers and not strings because im subtracting them with math
Are you sure those are tabs? You can specify no argument for split and it automatically splits on whitespace (which means you won't have to strip newlines beforehand either). I copied your sample into a file and got it to work like this:
allt = []
with open('towers1.txt','r') as f:
for line in f:
allt.append(line.split())
>>>print allt[0]
['mw91', '42.927', '-72.84', '2.8']
>>>print allt[0][1]
'42.927'
Footnote: if you get rid of your first list comprehension, you're only iterating the file once, which is less wasteful.
Just saw that you want help converting the float values as well. Assuming that line.split() splits up the data correctly, something like the following should probably work:
allt = []
with open('towers1.txt','r') as f:
for line in f:
first, *_else = line.split() #Python3
data = [first]
float_nums = [float(x) for x in _else]
data.extend(float_nums)
allt.append(data)
>>>print allt[0]
['mw91', 42.927, -72.84, 2.8]
For Python2, substitute the first, *_else = line.split() with the following:
first, _else = line.split()[0], line.split()[1:]
Finally (in response to comments below), if you want a list of a certain set of values, you're going to have to iterate again and this is where list comprehensions can be useful. If you want the [2] index value for each element in allt, you'll have to do something like this:
>>> some_items = [item[2] for item in allt]
>>> some_items
[-72.84, -72.58, -72.679]
[] implies a list.
'' implies a string.
allt = ['mw91 42.927 -72.84 2.8']
allt is a list that contains a string:
allt[0] --> 'mw91 42.927 -72.84 2.8'
allt[0][2] --> '9'
allt.split() --> ['mw91', '42.927', '-72.84', '2.8']
allt.split()[2] --> '-72.84' #This is still a string.
float(allt.split()[2]) --> -72.84 #This is now a float.
I think this should also work
with open('towers.txt', 'r') as f:
allt = map(str.split, f)
And if you need the values after the first one to be floats...
with open('towers.txt', 'r') as f:
allt = [line[:1] + map(float, line[1:]) for line in map(str.split, f)]

Next line escape character not working python

I used the following code to read from a text file line by line and print it on screen.
with open("source.txt") as f:
content = f.readlines()
print(content)
print('\n')
f.close()
But the \n was just getting appended to the output and the output was coming in a single line instead. For example if the file was like this:
abc
def
ghi
the output was:
['abc\n', 'def\n', 'ghi']
Then I tried changing the single quotes with the '\n' with "\n" like this:
with open("source.txt") as f:
content = f.readlines()
print(content)
print("\n")
f.close()
The actual output I need is:
abc
def
ghi
What can i do for that? Operating platform: Mac(Unix) Thanks in advance.
You should do it this way:
with open('source.txt', 'r') as f:
for line in f: #iterate over lines
line = line.strip() #removes whitespaces and new lines
print line #print the line, the print function adds new line
readlines() loads the whole file in memory and if the file is bigger than your memory you can't read it, so iterate over the file.
You can use rstrip():
>>> for i in content:
... print i.rstrip()
...
abc
def
ghi
The problem with your code is that it isn't doing what you would expect it to do. content is a list, and printing the list would just have ['abc\n', etc]. You can use a for-loop (as I have shown) to go through each element in the list and individually print out all the elements on a separate line.
I'm not exactly sure why you have print('\n'), but I'm presuming that you come from another programming language. Python automatically adds a newline, so adding one is not needed :).
Finally, rstrip() is needed to strip the newline, otherwise this would appear:
>>> for i in L:
... print i
...
abc
def
ghi
The problem is you were trying to print the list object itself, instead you should loop over the list and print individual items:
>>> lis = ['abc\n', 'def\n', 'ghi']
>>> print lis
['abc\n', 'def\n', 'ghi']
print lis actually prints the str representation of the list object:
>>> print str(lis)
['abc\n', 'def\n', 'ghi']
Loop over the list and print individual items. In python we can loop over the list itself unlike C/C++ where we require indexes.
>>> for item in lis:
... print item.rstrip('\n') #removes the trailing '\n'
...
abc
def
ghi
A for-loop over a list or any other iterable returns the next item from that iterable one by one and assigns it to the variable used in for-loop:
for x in lis: #in each iteration x is assgined the next item from lis
print x
with open('source.txt', 'r') as f:
content = f.read()
print content

Splitting up a text file into sets of n characters

So I have a long text file with a bunch of numbers and I want to reformat this file so that every 12 characters are on their own line, the file is 4392 characters long. My strategy was to add the contents of the infile to a list and slice and append the first 12 characters to a new list then write it to an outfile using a while loop for the list slicing parameters. I am getting an error on out.writelines(l) :
TypeError: writelines() argument must be a sequence of strings.
Here is my code:
l = []
outl=[]
with open('r6.txt', 'r') as f, \
open('out.txt', 'w') as out:
outl.append(f)
a = 0
b = 11
while b <= 4392:
l.append(outl[a:b])
l.append('/n')
out.writelines(l)
a+=12
b+=12
l=[]
Well you're appending the file object to the list, and then you're taking slices of the list and writing them. Perhaps you forgot the file object reference among the strings.
Just use a print outl to get your answer. If you've got a file object among the items in the list, then you know :)
OR better yet:
l = []
outl=[]
with open('r6.txt', 'r') as f, \
open('out.txt', 'w') as out:
outl.extend(f.readlines())
a = 0
b = 11
while b <= 4392:
l.append(outl[a:b])
l.append('\n')
out.writelines(l)
a+=12
b+=12
l=[]
Hm, although other answers seem to be correct, I still think that the final solution can be, well, faster:
with open('r6.txt', 'r') as f, \
open('out.txt', 'w') as out:
# call anonymous lambda function returning f.read(12) until output is '', put output to part
for part in iter(lambda: f.read(12), ''):
# write this part and newline character
out.write(part)
out.write('\n')
Vlad-ardelean is correct in saying you need to append f.readlines() to outl instead of the file f.
Also, you're using writelines() to write a single line each time, but writelines() is intended for writing out a list of strings to a file, not one item lists. Perhaps a better way to approach the insertion of newline characters would be:
l = []
outl=[]
with open('r6.txt', 'r') as f, \
open('out.txt', 'w') as out:
# gets entire file as one string and removes line breaks
outl = ''.join(f.readlines()).replace('\n','')
l = [outl[each:each+12]+'\n' for each in xrange(0,len(outl),12)]
out.writelines(l)
Sample input for r6:
abcdefeounv lernbtlttb
berolinervio
bnrtopimrtynprymnpobm,t
2497839085gh
b640h846j048nm5gh0m8-9
2g395gm4-59m46bn
2vb-9mb5-9046m-b946m-b946mb-96m-05n=570n;rlgbm'dfb
output:
abcdefeounv
lernbtlttbbe
rolinerviobn
rtopimrtynpr
ymnpobm,t249
7839085ghb64
0h846j048nm5
gh0m8-92g395
gm4-59m46bn2
vb-9mb5-9046
m-b946m-b946
mb-96m-05n=5
70n;rlgbm'df
b

Categories

Resources