在文件中find最小的浮点数,然后将其打印在上面

我的数据文件如下所示:

3.6-band 6238 Over 0.5678 Over 0.6874 Over 0.7680 Over 0.7834 

我想要做的是挑出最小的浮点数和正上方的单词,并打印这两个值。 我不知道我在做什么。 我试过了

 df=open('filepath') for line in df: df1=line.split() df2=min(df1) 

我试图至less试图隔离最小的浮点数。 问题是给我最后的价值。 我认为这是一个问题,python不知道重新开始,但再次…不知道我在做什么。 我试图df2=min(df1.seek(0))没有成功,得到一个错误,说no attribute seek 。 所以这就是我到目前为止的尝试,我仍然不知道如何打印最小浮点数之前的行。 build议/帮助/意见,将不胜感激,谢谢。

作为一个方面说明:这个数据文件是一个具有相似特征的较大文件的例子,但“Over”这个词也可能是“Under”,这就是为什么我需要打印它。

将这些项目存储在一个列表中, [word,num]对,然后在该列表上应用min 。 使用min key参数来指定哪个项目必须用于比较项目:

 with open('abc') as f: lis = [[line.strip(),next(f).strip()] for line in f] minn = min(lis, key = lambda x: float(x[1])) print "\n".join(minn) ... Over 0.5678 

这里lis看起来像这样:

 [['3.6-band', '6238'], ['Over', '0.5678'], ['Over', '0.6874'], ['Over', '0.7680'], ['Over', '0.7834']] 

您可以使用石斑鱼配方 izip(*[iterator]*2)df的行聚类为2组。然后,使用min及其key参数指定要用于的代理比较。 在这种情况下,对于每一对行(p, l) ,我们要使用第二行float(l)作为代理:

 import itertools as IT with open('filepath') as df: previous, minline = min(IT.izip(*[df]*2), key=lambda (p, l): float(l)) minline = float(minline) print(previous) print(minline) 

版画

 Over 0.5678 

石斑鱼配方的解释:

要了解石斑鱼配方,首先看看如果df是一个列表会发生什么:

 In [1]: df = [1, 2] In [2]: [df]*2 Out[2]: [[1, 2], [1, 2]] 

在Python中,当你用一个正整数n乘以一个列表时,你会得到列表中的n n (浅)副本。 因此, [df]*2列出了两个df副本。

现在考虑zip(*[df]*2)

用于zip(*...)具有特殊的含义。 它告诉Python将*后面的列表解压缩到要传递给zip参数中。 因此, zip(*[df]*2)完全等同于zip(df, df)

 In [3]: zip(df, df) Out[3]: [(1, 1), (2, 2)] In [4]: zip(*[df]*2) Out[4]: [(1, 1), (2, 2)] 

SaltyCrane在这里给出了一个更完整的参数解包解释 。

记下zip在做什么 。 zip(*[df]*2)剥离两个副本的第一个元素(在这种情况下都是1),并形成元组(1,1)。 然后剥离两个副本的第二个元素(都是2),并形成元组(2,2)。 它返回里面的这些元组的列表。

现在考虑当df是一个迭代器时会发生什么。 一个迭代器就像一个列表,除了一个迭代器只适用于单个遍。 当项目被拉出迭代器时,迭代器永远不能被倒回。

例如,文件句柄是一个迭代器。 假设我们有一个带有行的文件

 1 2 3 4 In [8]: f = open('data') 

你可以通过调用next(f)来从迭代器f取出项目:

 In [9]: next(f) Out[9]: '1\n' In [10]: next(f) Out[10]: '2\n' In [11]: next(f) Out[11]: '3\n' In [12]: next(f) Out[12]: '4\n' 

每次我们调用next(f) ,我们从文件句柄f得到下一行。 如果我们再次调用next(f) ,我们会得到一个StopIterationexception,说明迭代器是空的。

现在让我们来看看石斑鱼配方在fperformance:

 In [14]: f = open('data') # Notice we have to open the file again, since the old iterator is empty In [15]: [f]*2 Out[15]: [<open file 'data', mode 'r' at 0xa028f98>, <open file 'data', mode 'r' at 0xa028f98>] 

[f]*2给了我们一个列表,其中有两个相同的迭代器f

 In [16]: zip(*[f]*2) Out[16]: [('1\n', '2\n'), ('3\n', '4\n')] 

zip(*[f]*2)从第一个迭代器f剥离第一个项目,然后从第二个迭代器f剥离第一个项目。 但迭代器是相同的两次! 而且由于迭代器对于单次传递是有好处的(你永远不能回头),所以每当你剥离一个物品的时候你会得到不同的物品。 zip正在next(f)调用每次剥离一个项目。 所以第一个元组是('1\n', '2\n') 。 同样, zip然后从第一个迭代器f剥离下一个项目,然后从第二个迭代器f剥离下一个项目,并形成元组('3\n', '4\n') 。 因此, zip(*[f]*2)返回[('1\n', '2\n'), ('3\n', '4\n')]

石斑鱼配方就是这样。 上面,我select使用IT.izip而不是zip以便Python返回一个迭代器而不是元组列表。 如果文件中有很多行,这将节省大量的内存。 zipIT.izip的区别在这里有更详细的解释。

你不能使用:

 min(number) 

你只能使用:

 min(num1, num2) 

如果你的文件如下所示:

 6238 0.5678 0.6874 0.7680 0.7834 

你可以使用这个代码:

 Num1 = float(file.readline()) for line in file: Num2 = float(line) Num1 = min(Num1, Num2) 

如果你有"Over"那么你可以跳过每一行。

你需要读取文件的所有行,也许用File.readlines(),或者像你已经有的循环,然后为每行读取数字(如果它是一个数字),并比较“迄今为止最好的”值。

看起来你并不需要split()。 你需要做的是检查每行是否以数字开始。 如果是这样,你可以用float(line)来获得数字。 也许浮动(line.strip())如果空格造成麻烦。 如果该行不是以数字开头,请将其保存在一个临时variables中。 如果下一行certificate提供的数字小于最佳值,则可以将该临时值复制到临时输出的variables中。

上面我看到一些有趣的解决scheme 我会去这个简单的解决scheme。 还有一个问题,那就是整数可能会被这样做。 任何人都有这个解决scheme?

  df=open('myfile.txt') lines=df.readlines() minval = 1e99 for n,line in enumerate(lines): try: val=float(line) # NB! like this, also integers will be taken. if val < minval: minval = val i_min = n except: pass word = lines[i_min-1]