Python 如何比较一行中的字符串和下一行中的字符串?
我有一个大约16000行的文件。 它们都有相同的格式。以下是一个简单的示例,如果:Python 如何比较一行中的字符串和下一行中的字符串?,python,Python,我有一个大约16000行的文件。 它们都有相同的格式。以下是一个简单的示例,如果: ATOM 139 C1 DPPC 18 17.250 58.420 10.850 1.00 0.00 原子189 C1 DPPC 19 23.050 20.800 11.000 1.00 0.00 我需要检查包含字符串DPPC且标识符18的行是否在标识符切换到19之前形成50行块,等等 现在,我有以下代码: cnt = 0 with open('test_file.pdb') as f1: with o
ATOM 139 C1 DPPC 18 17.250 58.420 10.850 1.00 0.00
原子189 C1 DPPC 19 23.050 20.800 11.000 1.00 0.00
我需要检查包含字符串DPPC
且标识符18
的行是否在标识符切换到19
之前形成50行块,等等
现在,我有以下代码:
cnt = 0
with open('test_file.pdb') as f1:
with open('out','a') as f2:
lines = f1.readlines()
for i, line in enumerate(lines):
if "DPPC" in line:
A = line.strip()[22:26]
if A[i] == A [i+1]:
cnt = cnt + 1
elif A[i] != A[i+1]:
cnt = 0
我被困在这里了。我找到了一些如何比较后续行的示例,但类似的方法在这里不起作用。我仍然不知道如何将行[I]
中A
的值与行[I+1]
中A
的值进行比较(注释中的解释)
输出:
18: 9
19: 19
您还可以通过并行列表轻松解决此问题:
data = []
with open('data.txt', 'r') as datafile:
for line in datafile:
line=line.strip()
if line:
data.append(line);
keywordList = []
for line in data:
line = line.split()
if (line[4] not in keywordList):
keywordList.append(line[4])
counterList = []
for item in keywordList:
counter = 0
for line in data:
line = line.split()
if (line[4] == item):
counter+=1
counterList.append(counter)
for i in range(len(keywordList)):
print("%s: %d"%(keywordList[i],counterList[i]));
但是,如果您熟悉dict,我将使用Lutz的答案。由于您的数据在固定宽度记录中显示为固定宽度字段,您可以使用
struct
模块将每行快速分解为单独的字段
当您只需要处理其中一个字段时,解析每行的所有字段可能会有点过火,但我所用的方法说明了在您需要进行其他处理时是如何完成的,并且使用struct
模块在任何情况下都会使解析速度相对较快
假设输入文件仅包含以下数据行:
ATOM 139 C1 DPPC 18 17.250 58.420 10.850 1.00 0.00
原子139 C1 DPPC 18 17.250 58.420 10.850 1.00 0.00
原子139 C1 DPPC 18 17.250 58.420 10.850 1.00 0.00
原子139 C1 DPPC 18 17.250 58.420 10.850 1.00 0.00
原子139 C1 DPPC 18 17.250 58.420 10.850 1.00 0.00
原子139 C1 DPPC 18 17.250 58.420 10.850 1.00 0.00
原子139 C1 DPPC 18 17.250 58.420 10.850 1.00 0.00
原子139 C1 DPPC 18 17.250 58.420 10.850 1.00 0.00
原子139 C1 DPPC 18 17.250 58.420 10.850 1.00 0.00
原子189 C1 DPPC 19 23.050 20.800 11.000 1.00 0.00
原子189 C1 DPPC 19 23.050 20.800 11.000 1.00 0.00
原子189 C1 DPPC 19 23.050 20.800 11.000 1.00 0.00
原子189 C1 DPPC 19 23.050 20.800 11.000 1.00 0.00
原子189 C1 DPPC 19 23.050 20.800 11.000 1.00 0.00
原子189 C1 DPPC 19 23.050 20.800 11.000 1.00 0.00
原子189 C1 DPPC 19 23.050 20.800 11.000 1.00 0.00
原子189 C1 DPPC 20 23.050 20.800 11.000 1.00 0.00
原子189 C1 DPPC 20 23.050 20.800 11.000 1.00 0.00
原子189 C1 DPPC 20 23.050 20.800 11.000 1.00 0.00
您需要做的就是记住前一行字段的值,以便将其与当前字段进行比较。要启动该过程,必须分别读取和解析第一行,因此有一个prev
值可与后续行中的值进行比较。还要注意,第5个字段是由[4]
索引的字段,因为第一个字段从[0]
开始
import struct
# negative widths represent ignored padding fields
fieldwidths = 4, -4, 3, -2, 2, -2, 4, -3, 2, -6, 6, -2, 6, -2, 6, -2, 4, -2, 4
fmtstring = ' '.join('{}{}'.format(abs(fw), 'x' if fw < 0 else 's')
for fw in fieldwidths)
fieldstruct = struct.Struct(fmtstring)
parse = fieldstruct.unpack_from # a function to split line up into fields
with open('test_file.pdb') as f1:
prev = parse(next(f1))[4] # remember value of fifth field
cnt = 1
for line in f1:
curr = parse(line)[4] # get value of fifth field
if curr == prev: # same as last one?
cnt += 1
else:
print('{} occurred {} times'.format(prev, cnt))
prev = curr
cnt = 1
print('{} occurred {} times'.format(prev, cnt)) # for last line
我对你的问题理解正确吗?您想验证第5个字段中是否有一个50行的块,其中
18
,然后是19
,等等。您将a
定义为line.strip()[22:26]
,其中line
是i
-第行。那么,A[i+1]
是什么意思呢?是的,没错。在这个特殊的例子中,我想知道在第5列中有多少行包含18、19等。谢谢!我刚刚在我的数据集上测试了你的代码,它工作得非常好。
import struct
# negative widths represent ignored padding fields
fieldwidths = 4, -4, 3, -2, 2, -2, 4, -3, 2, -6, 6, -2, 6, -2, 6, -2, 4, -2, 4
fmtstring = ' '.join('{}{}'.format(abs(fw), 'x' if fw < 0 else 's')
for fw in fieldwidths)
fieldstruct = struct.Struct(fmtstring)
parse = fieldstruct.unpack_from # a function to split line up into fields
with open('test_file.pdb') as f1:
prev = parse(next(f1))[4] # remember value of fifth field
cnt = 1
for line in f1:
curr = parse(line)[4] # get value of fifth field
if curr == prev: # same as last one?
cnt += 1
else:
print('{} occurred {} times'.format(prev, cnt))
prev = curr
cnt = 1
print('{} occurred {} times'.format(prev, cnt)) # for last line