Read all columns from text file - python

I'm trying to read a text file. I need to read column values to list. My text file looks like this:
40 10 5 5
30 20 10 0
30 30 10 5
and desired output is
(40,30,30),(10,20,30),(5,10,10),(5,0,5)
I tried this code
def contest(filename):
contestFile = open(filename,'r')
contestFileLines=contestFile.readlines()
startColumn = 0
contestResult=[]
for x in contestFileLines:
contestResult.append(x.split()[startColumn])
contestFile.close()
print(contestResult)
contest("testing.txt")
and its output is just
['40', '30', '30']
What should I do?

Try reading every line into an list, splitting by each space and mapping to an int. Then, you can use this answer (which Barmar suggested in the comments) to transpose the list of map generators. Just like this:
def cols(path):
rows = []
with open(path) as f:
for line in f:
rows.append(map(int, line.split(' ')))
return list(map(list, zip(*rows)))
print(cols('test.txt')) # => [[40, 30, 30], [10, 20, 30], [5, 10, 10], [5, 0, 5]]
Alternatively, if you need the output as a tuple, just change this line:
return list(map(list, zip(*rows)))
to
return list(map(tuple, zip(*rows)))

Related

How to extract data from a text file and add it to a list?

Python noob here. I have this text file that has data arranged in particular way, shown below.
x = 2,4,5,8,9,10,12,45
y = 4,2,7,2,8,9,12,15
I want to extract the x values and y values from this and put them into their respective arrays for plotting graphs. I looked into some sources but could not find a particular solution as they all used the "readlines()" method that returns as a list with 2 strings. I can convert the strings to integers but the problem that I face is how do I only extract the numbers and not the rest?
I did write some code;
#lists for storing values of x and y
x_values = []
y_values = []
#opening the file and reading the lines
file = open('data.txt', 'r')
lines = file.readlines()
#splitting the first element of the list into parts
x = lines[0].split()
#This is a temporary variable to remove the "," from the string
temp_x = x[2].replace(",","")
#adding the values to the list and converting them to integer.
for i in temp_x:
x_value.append(int(i))
This gets the job done but the method I think is too crude. Is there a better way to do this?
You can use read().splitlines() and removeprefix():
with open('data.txt') as file:
lines = file.read().splitlines()
x_values = [int(x) for x in lines[0].removeprefix('x = ').split(',')]
y_values = [int(y) for y in lines[1].removeprefix('y = ').split(',')]
print(x_values)
print(y_values)
# output:
# [2, 4, 5, 8, 9, 10, 12, 45]
# [4, 2, 7, 2, 8, 9, 12, 15]
Since your new to python, here's a tip! : never open a file without closing it, it is common practice to use with to prevent that, as for your solution, you can do this :
with open('data.txt', 'r') as file:
# extract the lines
lines = file.readlines()
# extract the x and y values
x_values = [
int(el) for el in lines[0].replace('x = ', '').split(',') if el.isnumeric()
]
y_values = [
int(el) for el in lines[1].replace('y = ', '').split(',') if el.isnumeric()
]
# the final output
print(x_values, y_values)
output:
[2, 4, 5, 8, 9, 10, 12] [4, 2, 7, 2, 8, 9, 12, 15]
Used dictionary to store the data.
# read data from file
with open('data.txt', 'r') as fd:
lines = fd.readlines()
# store in a (x,y)-dictionary
out = {}
for label, coord in zip(('x', 'y'), lines):
# casting strings to integers
out[label] = list(map(int, coord.split(',')[1:]))
# display data
#
print(out)
#{'x': [4, 5, 8, 9, 10, 12, 45], 'y': [2, 7, 2, 8, 9, 12, 15]}
print(out['y'])
#[2, 7, 2, 8, 9, 12, 15]
In case desired output as list just substitute the main part with
out = []
for coord in lines:
# casting strings to integers
out.append(list(map(int, coord.split(',')[1:])))
X, Y = out

Python Extract Numbers from a file

So, I have a txt file with some integers which are between 0 and 50. I want to extract them and to use their values.
The txt file looks like:
1 2 40 23
2 34 12
3 12 1
I have tried something like:
with open(input_file, "r") as file:
lines = file.readlines()
for i in range(len(lines)):
l = lines[i].strip()
for c in range(1, len(l)-1):
if(l[c] >= '0' and l[c] <= '9' and (l[c+1] < '0' or l[c+1] > '9')):
# other code with those numbers
elif(l[c] >= '0' and l[c] <= '9' and (l[c+1] >= '0' and l[c+1] <= '9')):
# other code with those numbers
The problem is that I extract the two digits numbers, but I do also extract one digit two digits numbers.
Any solution?
Or this way:
my_array=[]
with io.open(inputfile, mode="r", encoding="utf-8") as f:
for line in f:
my_array=my_array+line.split()
results = list(map(int, myarray)) #convert to int
print(my_array)
Output:
[1, 2, 40, 23, 2, 34, 12, 3, 12, 1]
You can gather all the numbers in the file into a list like this:
import re
with open(input_file) as f:
print(list(map(int, re.findall('\d+', f.read()))))
Output:
[1, 2, 40, 23, 2, 34, 12, 3, 12, 1]
Note:
Use of re may be unnecessary in OP's case but included here because it allows for potential garbage in the input file

how to create a list of integers from a text file with multiple lines?

I need to write a program that reads a text file and returns the median of the numbers in the file. I think I have a good idea of how to approach this, but I got an AttributeError when running my program.
My question is: how do I make one list for the numbers in the text file? There are a total of 15 numbers, split across 5 lines in the file:
10 20 30
40 50 60
90 80 70
11 22 13
14 14 20
what I thought to do to create a list was:
num_list = fv.readlines()
num_list = num_list.split()
I thought this would read through all the lines of the file, then I could use the split function to create a list of the numbers. Now that I got an AttributeError: 'list' object has no attribute 'split', I'm unsure of what to do.
Without a solid expected result I assume you want all numbers in one list.
You can create an empty list then use list.extend as you loop through the file. You will need to cast them to int though. map is great for this:
num_list = []
with open('filename.txt') as fv:
for row in fv:
num_list.extend(map(int, row.split()))
More efficiently you can use re
import re
with open('filename.txt') as fv:
num_list = list(map(int, re.findall('\d+', fv.read())))
Result (for both above) will be:
[10, 20, 30, 40, 50, 60, 90, 80, 70, 11, 22, 13, 14, 14, 20]
Otherwise in sublists by line/row:
with open('filename.txt') as fv:
num_list = [list(map(int, row.split())) for row in fv]
Result for this:
[[10, 20, 30], [40, 50, 60], [90, 80, 70], [11, 22, 13], [14, 14, 20]]
I think that's what you want to do:
lines = fv.readlines()
num_list = []
for line in lines:
num_list.extend(line.split(' '))
num_list = [int(num.strip()) for num in num_list]
My answer is definitely a longer version but...
text = open('numbers.txt', 'r')
string = text.read()
string = string.replace('\n', ' ')
numbers = string.split(' ')
text.close()
#Print to see the result
print(numbers)

calculating a class avg from a file

For this function, I want the class average for each assignment. I get this error when I try to test my function. Can anyone please help me fix this?
I want to go through the columns and have something like this. After I split the list, I want to interleave the grades of the assignments and add the corresponding items. How do I do that and then calculate the average?
I want to have [99, 88, 77, 66][11, 22, 33, 44][78, 58, 68, 88]into [99, 11, 78][88, 22, 58][77, 33, 68][66, 44, 88]
for item in range(grades_list[4:]):
builtins.TypeError: 'list' object cannot be interpreted as an integer
Here is the file for my function.
Last Name,First Name,Student No.,uTORid,A1,A2,A3,A4
Smith, Joe,9911991199,smithjoe9,99,88,77,66
Ash, Wood,9912334456,ashwood,11,22,33,44
Full, Kare,9913243567,fullkare,78,58,68,88
def class_avg(open_file):
'''(file) -> list of float
Return a list of assignment averages for the entire class given the open
class file. The returned list should contain assignment averages in the
order listed in the given file. For example, if there are 3 assignments
per student, the returned list should 3 floats representing the 3
averages.
[a1_avg, a2_avg, a3_avg, a4_avg]
[62.666666666666664, 56.0, 59.333333333333336, 66.0]
'''
new_list = []
for line in open_file:
grades_list = line.split(',')
for item in range(grades_list[4:]):
total = sum(grades_list[4:][item])
avg = total/len(grades_list[4:])
new_list.append(avg)
return new_list
There are a couple problems in your code.
You need to skip the header line ("Last Name,First Name,Student No.,uTORid,A1,A2,A3,A4")
You're also calculating multiple averages per student (for the first row, your code essentially does (9 + 9) / 2, (8 + 8) / 2, etc)
Also, it seems like you are trying to read down the columns, but that doesn't work
Something like this might work for you:
averages = []
with open('class_avg.csv') as fp:
next(fp) # skip header row
reader = csv.reader(fp)
for student_row in reader:
grades = student_row[4:] # extract columns 4, 5, 6, and 7 all at once
total = sum(float(grade) for grade in grades)
average = total / len(grades)
averages.append(average)
print(averages)
Create a 2d list .....
Read all the lines and then just do computation on the colomns you want output for ...
Accessing the column is something like
#example in python console
>>> list = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> new_list = [item[1] for item in list]
>>> new_list
[2, 5, 8]

Python: Partial sum of numbers [duplicate]

This question already has answers here:
How to find the cumulative sum of numbers in a list?
(25 answers)
Closed 8 years ago.
can you help me with code which returns partial sum of numbers in text file?
I must import text file, then make a code for partial sums without tools ..etc.
My input:
4
13
23
21
11
The output should be (without brackets or commas):
4
17
40
61
72
I was trying to make code in python, but could only do total sum and not partial one.
If i use the += operator for generator, it gives me an error!
Well, since everyone seems to be giving their favourite idiom for solving the problem, how about itertools.accumulate in Python 3:
>>> import itertools
>>> nums = [4, 13, 23, 21, 11]
>>> list(itertools.accumulate(nums))
[4, 17, 40, 61, 72]
There are a number of ways to create your sequence of partial sums. I think the most elegant is to use a generator.
def partial_sums(iterable):
total = 0
for i in iterable:
total += i
yield total
You can run it like this:
nums = [4, 13, 23, 21, 11]
sums = list(partial_sums(nums)) # [ 4, 17, 40, 61, 72]
Edit To read the data values from your file, you can use another generator, and chain them together. Here's how I'd do it:
with open("filename.in") as f_in:
# Sums generator that "feeds" from a generator expression that reads the file
sums = partial_sums(int(line) for line in f_in)
# Do output:
for value in sums:
print(value)
# If you need to write to a file, comment the loop above and uncomment this:
# with open("filename.out", "w") as f_out:
# f_out.writelines("%d\n" % value for value in sums)
numpy.cumsum will do what you want.
If you're not using numpy, you can write your own.
def cumsum(i):
s = 0
for elt in i:
s += elt
yield s
try this:
import numpy as np
input = [ 4, 13, 23, 21, 11 ]
output = []
output.append(input[0])
for i in np.arange(1,len(input)):
output.append(input[i] + input[i-1])
print output
Use cumulative sum in numpy:
import numpy as np
input = np.array([4, 13, 23, 21 ,11])
output = input.cumsum()
Result:
print output
>>>array([ 4, 17, 40, 61, 72])
Or if you need a list, you may convert output to list:
output = list(output)
print output
>>>[4, 17, 40, 61, 72]
This is an alternative solution using reduce:
nums = [4, 13, 23, 21, 11]
partial_sum = lambda a, b: a + [a[-1] + b]
sums = reduce(partial_sum, nums[1:], nums[0:1])
Pluses in lambda are not the same operator, the first one is list concatenation and the second one is sum of two integers. Altough Blckknght's may be more clear, this one is shorter and works in Python 2.7.
something like this:
>>> lst = [4, 13, 23, 21 ,11]
>>> [sum(lst[:i+1]) for i, x in enumerate(lst)]
[4, 17, 40, 61, 72]

Categories