Python3 - list index out of range - extracting data from file - python

I want to extract data from a file and change the value of an entry with a 'for-loop'.
f = open(r"C:\Users\Measurement\LOGGNSS.txt", "r")
x=0
content = [[],[]]
for line in f:
actualline = line.strip()
content.append(actualline.split(","))
x+=1
f.close
print(x)
for z in range(x):
print(z)
print(content[z][1])
IndexError: list index out of range
Using a real value instead of the variable 'z' works fine. But I need to change all first entries in the whole 2D-Array.
Why it does not work?

Your code has several problems.
First of all, use the with statement to open/close files correctly.
Then, you don't need to use a variable like x to keep track of the number of lines, just use enumerate() instead!
Here is how I would refactor your code to make it slimmer and more readable.
input_file = r"C:\Users\Measurement\LOGGNSS.txt"
content = []
with open(input_file, 'r') as f:
for line in f:
clean_line = line.strip().split(",")
content.append(clean_line)
for z, data in enumerate(content):
print(z,'\n',data)
Note that you could print the content while reading the file in one single loop.
with open(input_file, 'r') as f:
for z, line in enumerate(f):
clean_line = line.strip().split(",")
content.append(clean_line)
print(z,'\n', clean_line)
Finally, if you are dealing with a plain and simple csv file, then use the csv module from the standard library.
import csv
with open(input_file, 'r') as f:
content = csv.reader(f, delimiter=',')

You initialize your content with two empty arrays, so both of these will fail to find the first index ([1]), just initialize it with an empty array
content = []

Related

Adding text files content into a list of lists

I want to "read" the content of many txt files I have in a dir, to a list.
The thing is that I want every object in the list to be a list too.
I'd like to be able to access each "file" (or content of a file) by the index - in order to later train it with an NLP model. Also, that's why I used the line.strip() because I need each content to be stripped into "lines".
Here is the code I tried, however, I get the Error:
IndexError: list index out of range
os.chdir(r'C:\Users\User1\Article\BBC\bbc\entertainment')
ent_txts = glob.glob('*.txt')
ent_docs = []
d=0
for i in ent_txts:
with open(i, 'r') as f:
for line in f:
ent_docs[d].append(line.strip())
d+=1
I think the problem is with the fact that I'm trying to address a list index that hasn't been created.
I'm sure there's must be a simple way to do it, though I can't find it.
I'd be glad for any help!
The error is because you don't have any inner list to insert to. I would fix it like so:
for i in ent_txts:
with open(i, 'r') as f:
file_lines = [line.strip() for line in f]
ent_docs.append(file_lines)
from collections import defaultdict
os.chdir(r'C:\Users\User1\Article\BBC\bbc\entertainment')
ent_txts = glob.glob('*.txt')
ent_docs = defaultdict(list)
d=0
for i in ent_txts:
with open(i, 'r') as f:
for line in f:
ent_docs[d].append(line.strip())
d+=1

Write the first word/letter of each line to a new file

I have a file 'master.sql' that contains:
a.b.c
d.e.f
g.h.i
and I want to write on 'databases.sql' just the first letters, like this:
a
d
g
Here is my code, but returns just the last letter, the 'g'.
with open ('master.sql', 'r') as f:
for line in f:
x=(line.split('.')[0])
with open('databases.sql', 'w') as f:
f.write(str(x))
How can I fix this?
You'll need to write your data as you read it, otherwise you're not going to be able to do what you want. Fortunately, with allows you to open multiple files concurrently. This should work for you.
with open ('master.sql', 'r') as f1, open('databases.sql', 'w') as f2:
for line in f1:
f2.write(line.split('.')[0] + '\n')
Don't forget to write a newline, because file.write doesn't add one automatically.
Using list:
x = []
with open('master.sql', 'r') as f:
for line in f.readlines():
x.append(line.split('.')[0])
with open('databases.sql', 'w') as f:
for word in x:
f.write(str(word)+'\n')
The variable x receives all values, but each loop overwrite the last value. Hence, the result is 'g'.
To save all values you can do like this:
lst = []
with open ('master.sql', 'r') as f:
for line in f:
lst.append(line.split('.')[0])
x = '\n'.join(lst)
with open('databases.sql', 'w') as f:
f.write(x)

Convert first 2 elements of tuple to integer

I have a csv file with the following structure:
1234,5678,"text1"
983453,2141235,"text2"
I need to convert each line to a tuple and create a list. Here is what I did
with open('myfile.csv') as f1:
mytuples = [tuple(line.strip().split(',')) for line in f1.readlines()]
However, I want the first 2 columns to be integers, not strings. I was not able to figure out how to continue with this, except by reading the file line by line once again and parsing it. Can I add something to the code above so that I transform str to int as I convert the file to list of tuples?
This is a csv file. Treat it as such.
import csv
with open("test.csv") as csvfile:
reader = csv.reader(csvfile)
result = [(int(a), int(b), c) for a,b,c in reader]
If there's a chance your input may not be what you think it is:
import csv
with open('test.csv') as csvfile:
reader = csv.reader(csvfile)
result = []
for line in reader:
this_line = []
for col in line:
try:
col = int(col)
except ValueError:
pass
this_line.append(col)
result.append(tuple(this_line))
Instead of trying to cram all of the logic in a single line, just spread it out so that it is readable.
with open('myfile.csv') as f1:
mytuples = []
for line in f1:
tokens = line.strip().split(',')
mytuples.append( (int(tokens[0]), int(tokens[1]), tokens[2]) )
Real python programmers aren't afraid of using multiple lines.
You can use isdigit() to check if all letters within element in row is digit so convert it to int , so replace the following :
tuple(line.strip().split(','))
with :
tuple(int(i) if i.isdigit() else i for i in (line.strip().split(','))
You can cram this all into one line if you really want, but god help me I don't know why you'd want to. Try giving yourself room to breathe:
def get_tuple(token_list):
return (int(token_list[0]), int(token_list[1]), token_list[2])
mytuples = []
with open('myfile.csv') as f1:
for line in f1.readlines():
token_list = line.strip().split(',')
mytuples.append(get_tuple(token_list))
Isn't that way easier to read? I like list comprehension as much as the next guy, but I also like knowing what a block of code does when I sit down three weeks later and start reading it!

Opening a file in Python

Question:
How can I open a file in python that contains one integer value per line. Make python read the file, store data in a list and then print the list?
I have to ask the user for a file name and then do everything above. The file entered by the user will be used as 'alist' in the function below.
Thanks
def selectionSort(alist):
for index in range(0, len(alist)):
ismall = index
for i in range(index,len(alist)):
if alist[ismall] > alist[i]:
ismall = i
alist[index], alist[ismall] = alist[ismall], alist[index]
return alist
I think this is exactly what you need:
file = open('filename.txt', 'r')
lines = [int(line.strip()) for line in file.readlines()]
print(lines)
I didn't use a with statement here, as I was not sure whether or not you intended to use the file further in your code.
EDIT: You can just assign an input to a variable...
filename = input('Enter file path: ')
And then the above stuff, except open the file using that variable as a parameter...
file = open(filename, 'r')
Finally, submit the list lines to your function, selectionSort.
selectionSort(lines)
Note: This will only work if the file already exists, but I am sure that is what you meant as there would be no point in creating a new one as it would be empty. Also, if the file specified is not in the current working directory you would need to specify the full path- not just the filename.
Easiest way to open a file in Python and store its contents in a string:
with open('file.txt') as f:
contents = f.read()
for your problem:
with open('file.txt') as f:
values = [int(line) for line in f.readlines()]
print values
Edit: As noted in one of the other answers, the variable f only exists within the indented with-block. This construction automatically handles file closing in some error cases, which you would have to do with a finally-construct otherwise.
You can assign the list of integers to a string or a list
file = open('file.txt', mode = 'r')
values = file.read()
values will have a string which can be printed directly
file = open('file.txt', mode = 'r')
values = file.readlines()
values will have a list for each integer but can't be printed directly
f.readlines() read all the lines in your file, but what if your file contains a lot of lines?
You can try this instead:
new_list = [] ## start a list variable
with open('filename.txt', 'r') as f:
for line in f:
## remove '\n' from the end of the line
line = line.strip()
## store each line as an integer in the list variable
new_list.append(int(line))
print new_list

Copy the last three lines of a text file in python?

I'm new to python and the way it handles variables and arrays of variables in lists is quite alien to me. I would normally read a text file into a vector and then copy the last three into a new array/vector by determining the size of the vector and then looping with a for loop a copy function for the last size-three into a new array.
I don't understand how for loops work in python so I can't do that.
so far I have:
#read text file into line list
numberOfLinesInChat = 3
text_file = open("Output.txt", "r")
lines = text_file.readlines()
text_file.close()
writeLines = []
if len(lines) > numberOfLinesInChat:
i = 0
while ((numberOfLinesInChat-i) >= 0):
writeLine[i] = lines[(len(lines)-(numberOfLinesInChat-i))]
i+= 1
#write what people say to text file
text_file = open("Output.txt", "w")
text_file.write(writeLines)
text_file.close()
To get the last three lines of a file efficiently, use deque:
from collections import deque
with open('somefile') as fin:
last3 = deque(fin, 3)
This saves reading the whole file into memory to slice off what you didn't actually want.
To reflect your comment - your complete code would be:
from collections import deque
with open('somefile') as fin, open('outputfile', 'w') as fout:
fout.writelines(deque(fin, 3))
As long as you're ok to hold all of the file lines in memory, you can slice the list of lines to get the last x items. See http://docs.python.org/2/tutorial/introduction.html and search for 'slice notation'.
def get_chat_lines(file_path, num_chat_lines):
with open(file_path) as src:
lines = src.readlines()
return lines[-num_chat_lines:]
>>> lines = get_chat_lines('Output.txt', 3)
>>> print(lines)
... ['line n-3\n', 'line n-2\n', 'line n-1']
First to answer your question, my guress is that you had an index error you should replace the line writeLine[i] with writeLine.append( ). After that, you should also do a loop to write the output :
text_file = open("Output.txt", "w")
for row in writeLine :
text_file.write(row)
text_file.close()
May I suggest a more pythonic way to write this ? It would be as follow :
with open("Input.txt") as f_in, open("Output.txt", "w") as f_out :
for row in f_in.readlines()[-3:] :
f_out.write(row)
A possible solution:
lines = [ l for l in open("Output.txt")]
file = open('Output.txt', 'w')
file.write(lines[-3:0])
file.close()
This might be a little clearer if you do not know python syntax.
lst_lines = lines.split()
This will create a list containing all the lines in the text file.
Then for the last line you can do:
last = lst_lines[-1]
secondLAst = lst_lines[-2]
etc... list and string indexes can be reached from the end with the '-'.
or you can loop through them and print specific ones using:
start = start line, stop = where to end, step = what to increment by.
for i in range(start, stop-1, step):
string = lst_lines[i]
then just write them to a file.

Categories