在文件中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,说明迭代器是空的。
现在让我们来看看石斑鱼配方在f
performance:
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返回一个迭代器而不是元组列表。 如果文件中有很多行,这将节省大量的内存。 zip
和IT.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]