我的数据文件如下所示:
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)
这是我尝试至少尝试隔离最小浮子的尝试。问题是它只是给了我最后一个值。我认为这是一个python的问题,不知道重复迭代,但再次......不知道我在做什么。我尝试了df2=min(df1.seek(0))
但没有成功,收到错误说no attribute seek
。所以这就是我到目前为止所尝试的,我仍然不知道如何打印最小浮动之前的行。建议/帮助/建议将不胜感激,谢谢。
作为旁注:这个数据文件是一个具有相似特征的较大的文件的例子,但是“Over”这个词也可能是“Under”,这就是我需要打印它的原因。
答案 0 :(得分:2)
将项目存储在列表[word,num]
对列表中,然后在列表列表中应用min
。使用key
min
参数指定必须使用哪个项目来比较项目。:
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']]
答案 1 :(得分:2)
您可以使用grouper recipe,izip(*[iterator]*2)
将df
中的行聚为2组。然后,要找到最小的对行,使用min
and its key
parameter指定用于比较的代理。在这种情况下,对于每对行(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
(浅)
列表中项目的副本。因此,[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)]
A more complete explanation of argument unpacking is given by SaltyCrane here。
记下what zip
is doing。
zip(*[df]*2)
剥离两个副本的第一个元素(在这种情况下均为1),
形成元组,(1,1)。然后它剥离两个副本的第二个元素(两个都是2),并形成元组(2,2)。它返回一个包含这些元组的列表。
现在考虑当df
是迭代器时会发生什么。迭代器有点像列表,除了迭代器只适用于一次传递。当项目从迭代器中拉出时,迭代器永远不会被重绕。
例如,文件句柄是迭代器。 假设我们有一个带行
的文件1
2
3
4
In [8]: f = open('data')
您可以通过调用f
将项目从迭代器next(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)
,我们会得到一个StopIteration异常,表明迭代器是空的。
现在让我们看看石斑鱼配方在f
上的行为:
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
剥离第一个项目。 但迭代器是
两次都是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')]
。
这就是石斑鱼食谱的全部内容。在上面,我选择使用IT.izip
而不是zip
,以便Python返回迭代器而不是元组列表。如果文件中有很多行,这将节省大量内存。 zip
和IT.izip
之间的差异更加全面地解释了here。
答案 2 :(得分:1)
你不能使用:
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"
s,那么你可以跳过每一行。
答案 3 :(得分:0)
您需要读取文件的所有行,可能使用File.readlines(),或者您已经拥有的循环,然后为每行读取数字(如果是数字)并与“最佳”进行比较到目前为止“价值。
看起来你真的不需要split()。你需要做的是检查每一行是否以数字开头。如果是这样,您可以使用float(行)获取数字。如果空格引起麻烦,可能是float(line.strip())。如果该行不以数字开头,请将其保存在临时变量中。如果下一行证明提供的数字低于最佳最佳值,则可以将该临时值复制到临时输出的变量中。
答案 4 :(得分:0)
我在上面看到了一些有趣的解决方案。我会选择这个直截了当的解决方案。还有一个问题,那就是整数也可能是这样的。有人解决这个问题吗?
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]