Reputation: 757
I have a file 1.txt containing words and symbols on some lines while on other lines I have only numbers, and never no numbers are on the same line where words and symbols are.
FOO >
1.0
BAR <
0.004
FOO FOO <
0.000004
BAR BAR <
What I need is to analyze only the lines that have numbers, and then compare the numbers found and print the maximum value and minimum value.
In addition it is important that I know the line number (instead index) of the minimum value and the maximum value.
I tried to solve this looking at some questions like
Find Min and Max from Text File - Python e How to Find Minimum value from *.txt file
But, for example, when I run the code
import csv
rows = []
with open('1.txt', mode='r') as infile:
reader = csv.reader(infile, delimiter=" ")
for row in reader: # each row is a list
rows.append(row)
minimus = min(rows, key=lambda x: float(x[0]))
print(minimus)
I have bumped into the following error
ValueError: could not convert string to float: 'FOO'
How could I escape the lines that have symbols and words and just analyze the lines that have numbers, also obtaining the indicator of the lines with the minimum and maximum value?
I could extract all the rows that contains only numbers to a new file (for example using regex), but I would need to know the previous/after line to the line that the minimum value was found, then any line extraction would increase the number of steps of the analysis in which I am involved because I would have to return to analyze the original 1.txt file.
Note: I am inexperienced in Python compared to a frequent user of this language, but I think it is something simple for stackoverflow Questions list, and I suspect that perhaps this issue has already been answered. But as I already looked for some satisfactory question and I did not find it so I'm doing my own question.
Upvotes: 2
Views: 2085
Reputation: 2129
One possible approach without the need for any extra modules
Code:
def is_float(x):
try:
float(x)
return True
except:
return False
with open('url1.txt', 'r') as myfile:
lines = myfile.readlines()
nums = [x for x in lines if is_float(x)]
my_min = min(nums)
my_max = max(nums)
print('Max: ', my_max, 'line number: ', lines.index(my_max)+1)
print()
print('Min: ', my_min, 'line number: ', lines.index(my_min)+1)
Input:
FOO >
1.0
BAR <
0.004
FOO FOO <
0.000004
BAR BAR <
Output:
Max: 1.0
line number: 2
Min: 0.000004
line number: 6
Explanation:
try
statement and float()
list.index(<value>)
Upvotes: 2
Reputation: 5347
import csv
rows = []
with open('1.txt', mode='r') as infile:
reader = csv.reader(infile, delimiter=" ")
for row in reader:
if not row[0].isalpha():
rows.append(row[0])
print(rows)
minimus = min(rows, key=lambda x: float(x[0]))
print(minimus)
Incorporate an if
statement to check if the row[0]
is not an alpha
str.isalpha() Return True if all characters in the string are alphabetic and there is at least one character, False otherwise
Upvotes: 0
Reputation: 215
I suggest a simple solution by collecting all numbers and their indices using a try except statement. After the number and indices are collected in two lists you can find the min and max by for instance making use of the numpy package.
import numpy as np
numbers, indices = [],[]
with open("1.txt") as my_text_file:
for i, line in enumerate( my_text_file.readlines() ):
try:
numbers.append( float(line) )
indices.append( i )
except:
pass
maxvalue = np.max( numbers )
minvalue = np.min( numbers )
maxindx = indices[ np.argmax( numbers ) ]
minindx = indices[ np.argmin( numbers ) ]
print("The maximum value is found at line "+str(maxindx)+" with the value "+str(maxvalue))
print("The minimum value is found at line "+str(minindx)+" with the value "+str(minvalue))
For the provided 1.txt file thisproduces theprint out
The maximum value is found at line 1 with the value 1.0
The minimum value is found at line 5 with the value 4e-06
Cheers
Upvotes: 0
Reputation: 530
This might be overkill, but what immediately came to my mind is RegEx (Regular Expressions), using the re
library.
Here's the RegEx you would use for a float: ^[1-9]\d*(\.\d+)?$
. So we can implement this code:
import csv
import re
rows = []
with open('1.txt', mode='r') as infile:
reader = csv.reader(infile, delimiter=" ")
for row in reader: # each row is a list
if bool(re.match(r'^[1-9]\d*(\.\d+)?$', row): rows.append(row)
minimus = min(rows, key=lambda x: float(x[0]))
print(minimus)
What I changed:
I added if bool(re.match...
, resulting in rows
only getting appended to under the circumstance that row
is only a float (or integer).
Upvotes: 1