Python 使用“startswith”和“next”命令从文件中选择行

Python 使用“startswith”和“next”命令从文件中选择行,python,readlines,startswith,Python,Readlines,Startswith,我有一个文件,我想从中创建一个列表timestep,其中的数字显示在每行项目之后:timestep so: timestep = [253400, 253500, .. etc] 以下是我拥有的文件示例: ITEM: TIMESTEP 253400 ITEM: NUMBER OF ATOMS 378 ITEM: BOX BOUNDS pp pp pp -2.6943709180241954e-01 5.6240920636804063e+01 -2.8194230631882372e-01 5

我有一个文件,我想从中创建一个列表timestep,其中的数字显示在每行项目之后:timestep so:

timestep = [253400, 253500, .. etc]
以下是我拥有的文件示例:

ITEM: TIMESTEP
253400
ITEM: NUMBER OF ATOMS
378
ITEM: BOX BOUNDS pp pp pp
-2.6943709180241954e-01 5.6240920636804063e+01
-2.8194230631882372e-01 5.8851195163321044e+01
-2.7398090193568775e-01 5.7189372326936599e+01
ITEM: ATOMS id type q x y z 
16865 3 0 28.8028 1.81293 26.876 
16866 2 0 27.6753 2.22199 27.8362 
16867 2 0 26.8715 1.04115 28.4178 
16868 2 0 25.7503 1.42602 29.4002 
16869 2 0 24.8716 0.25569 29.8897 
16870 3 0 23.7129 0.593415 30.8357 
16871 3 0 11.9253 -0.270359 31.7252 
ITEM: TIMESTEP
253500
ITEM: NUMBER OF ATOMS
378
ITEM: BOX BOUNDS pp pp pp
-2.6943709180241954e-01 5.6240920636804063e+01
-2.8194230631882372e-01 5.8851195163321044e+01
-2.7398090193568775e-01 5.7189372326936599e+01
ITEM: ATOMS id type q x y z 
16865 3 0 28.8028 1.81293 26.876 
16866 2 0 27.6753 2.22199 27.8362 
16867 2 0 26.8715 1.04115 28.4178 
16868 2 0 25.7503 1.42602 29.4002 
16869 2 0 24.8716 0.25569 29.8897 
16870 3 0 23.7129 0.593415 30.8357 
16871 3 0 11.9253 -0.270359 31.7252
为此,我尝试立即使用startswith和next命令,但没有成功。还有别的办法吗?我还发送了我尝试使用的代码:


timestep = []
with open(file, 'r') as f:
    lines = f.readlines()
    for line in lines:
        line = line.split()
        if line[0].startswith("ITEM: TIMESTEP"):
            timestep.append(next(line))     
            print(timestep)



您可以使用enumerate来帮助索引引用。我们可以检查字符串项:TIMESTEP是否在前一行中,然后将整数添加到TIMESTEP列表中

timestep = []
with open('example.txt', 'r') as f:
    lines = f.readlines()
    for i, line in enumerate(lines):
        if "ITEM: TIMESTEP" in lines[i-1]:
            timestep.append(int(line.strip()))
            print(timestep)

逻辑是决定是否将当前行附加到timestep。因此,您需要的是一个变量,它告诉您在该变量为真时追加当前行

timestep = []
append_to_list = False # decision variable

with open(file, 'r') as f:
    lines = f.readlines()
    for line in lines:
        line = line.strip() # remove "\n" from line
        if line.startswith("ITEM"):
            # Update add_to_list
            if line == 'ITEM: TIMESTEP':
                append_to_list = True
            else:
                append_to_list = False
        else:
            # append to list if line doesn't start with "ITEM" and append_to_list is TRUE
            if append_to_list:
                timestep.append(line)
print(timestep)
输出:

['253400', '253500']


因此,代码的问题很微妙。您有一个迭代的列表行,但不能调用列表中的next

相反,将它转换为显式迭代器,您应该会很好

timestep=[] 使用openfile,“r”作为f: 行=f.readlines 线=线 对于串联式iter: line=line.strip删除换行符 如果line.startswithITEM:TIMESTEP: timestep.appendnextlines\u iter,None此处的第二个参数可防止出现错误 当ITEM:TIMESTEP显示为 文件中的最后一行 printtimestep 我也不确定为什么包含line.split,这在任何情况下都是不正确的line.split[0]。startswith'ITEM:TIMESTEP'永远不能为true,因为拆分会将ITEM:和TIMESTEP分离到结果列表的单独元素中

<>一个更稳妥的答案,考虑基于行以项目开始时分组数据。

def过程文件: 项目\标记='项目:' 项目名称='无' 值=[] 对于f中的行: 如果line.STARTS带有项目\标记: 如果值为: 收益项目名称、价值 item_title=行[lenITEM_MARKER:]。去掉标记 值=[] 其他: values.appendline.strip 如果值为: 收益项目名称、价值 这将允许您传入整个文件,并为每个项惰性地生成一组值:group。然后,您可以以某种合理的方式进行聚合

使用openfile,“r”作为f: 组=进程文件f 聚合={} 对于名称,组中的值: aggregations.setdefaultname,[].ExtendValue printaggregations['TIMESTEP']这是您想要的
首先,我不喜欢这个,因为它不能缩放。你只能很好地得到紧跟其后的第一行,其他任何东西都会很好

但是你问了,所以。。。for x in line将在行上创建一个迭代器,并使用该迭代器保持位置。您没有访问该迭代器的权限,因此next将不是您期望的下一个元素。但您可以制作自己的迭代器并使用它:

lines_iter = iter(lines)
for line in lines_iter:
    # whatever was here
                timestep.append(next(line_iter))     
然而,如果你想扩展它。。。对于这样的文件,for不是迭代的好方法。你想知道下一行/上一行是什么。我建议使用while:


通过这种方式,您可以将其扩展到不同类型的可变长度项。

请注意,您可能完全跳过f.readlines,只需通过fThere操作。这里有一个split命令,因为我希望避免在每个列表元素后面都有“\n”。我知道strip也可以使用,所以我只是想看看它会对结果产生什么影响。@kata248我添加了一个关于使这成为一个更健壮的解决方案的部分。谢谢你的回答,我也将你的代码用于其他目的。您能告诉我如何从某一行例如ITEM:TIMESTEP附加后面的所有行吗?它可以是每行的字符串形式。我这样问是因为我想在您编写的代码中添加/修改一段代码。如果看到ITEM:TIMESTEP,您可以创建一个布尔标志并将其从False更改为True。
timestep = []
with open('example.txt', 'r') as f:
    lines = f.readlines()
i = 0
while i < len(lines):
    if line[i].startswith("ITEM: TIMESTEP"):
       i += 1
       while not line[i].startswith("ITEM: "):
           timestep.append(next(line))     
           i += 1
    else:
       i += 1