octain
octain

Reputation: 964

Find the smallest float in a file and printing the line

I have a data file like this:

1 13.4545
2 10.5578
3 12.5578
4 5.224

I am trying to find the line with the smallest float number and print or write the entire line (including the integer) to another file. so i get this:

4 5.224

I have this but does not work:

with open(file) as f:
    small = map(float, line)
    mini = min(small)
    print mini

also tried using this:

with open(file) as f:
    mylist = [[line.strip(),next(f).strip()] for line in f]
    minimum = min(mylist, key = lambda x: float(x[1]))
    print minimum

Upvotes: 3

Views: 281

Answers (4)

Bhargav Rao
Bhargav Rao

Reputation: 52151

You were quite near, this is the minimal edit needed

with open(fl) as f:                             # don't use file as variable name
    line = [i.strip().split() for i in f]       # Get the lines as separate line no and value
    line = [(x[0],float(x[1])) for x in line]   # Convert the second value in the file to float
    m = min(line,key =  lambda x:x[1])          # find the minimum float value, that is the minimum second argument.
    print "{} {}".format(m[0],m[1])             # print it. Hip Hip Hurray \o/

Upvotes: 2

dawg
dawg

Reputation: 104024

Using your data file, we can iterate over each line of the file inside min since min takes an iterator:

>>> with open(fn) as f:
...    print min(f)
... 
1 13.4545

Obviously, that is using the ascii value of the integer for determining min.

Python's min takes a key function:

def kf(s):
    return float(s.split()[1])

with open(fn) as f:
    print min(f, key=kf)

Or:

>>> with open(fn) as f:
...    print min(f, key=lambda line: float(line.split()[1]))
... 
4 5.224

The advantage (in both versions) is that the file is processed line by line -- no need to read the entire file into memory.

The entire line is printed but only the float part is used to determine the min value of that line.


To fix YOUR version, the issue is your first list comprehension. Your version has next() in it which you probably thought was the next number. It isn't: It is the next line:

>>> with open(fn) as f:
...      mylist = [[line.strip(),next(f).strip()] for line in f]
... 
>>> mylist
[['1 13.4545', '2 10.5578'], ['3 12.5578', '4 5.224']]

The first list comprehension should be:

>>> with open(fn) as f:
...    mylist=[line.split() for line in f]
... 
>>> mylist
[['1', '13.4545'], ['2', '10.5578'], ['3', '12.5578'], ['4', '5.224']]

Then the rest will work OK (but you will have the split list in this case -- not the line -- to print):

>>> minimum=min(mylist, key = lambda x: float(x[1]))
>>> minimum
['4', '5.224']

Upvotes: 5

Vivek Sable
Vivek Sable

Reputation: 10223

map:

map(function, iterable, ...) Apply function to every item of iterable and return a list of the results. Link

Demo:

>>> map(float , ["1.9", "2.0", "3"])
[1.9, 2.0, 3.0]

>>> map(float , "1.9")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: could not convert string to float: .
>>> 

  1. Read input file by csv module because structure of input file is fixed.
  2. Set small and small_row variables to None.
  3. Read file row by row.
  4. Type Casting of second item from the row, from string to float.
  5. Check small variable is None or less then second item of row.
  6. If yes the assign small value and small_row respectivly

Demo:

import csv

file1 = "1_d.txt"

small = None
small_row = None
with open(file1) as fp:
    root = csv.reader(fp, delimiter=' ')
    for row in root:
        item = float(row[1])
        if small==None or small>item:
            small = item
            small_row = row

print "small_row:", small_row

Output:

$ python 3.py 
small_row: ['4', '5.224']

Upvotes: 0

ForceBru
ForceBru

Reputation: 44878

a=open('d.txt','r')

d=a.readlines()
m=float(d[0].split()[1])

for x in d[1:]:
    if float(x.split()[1])<m:
        m=float(x.split()[1])

print m

Upvotes: 0

Related Questions