Python 仅在文本文件中的特定位置执行操作
Python perform actions only at certain locations in text file
我有一个文本文件,其中包含这样的数据
AA 331
line1 ...
line2 ...
% information here
AA 332
line1 ...
line2 ...
line3 ...
%information here
AA 1021
line1 ...
line2 ...
% information here
AA 1022
line1 ...
% information here
AA 1023
line1 ...
line2 ...
% information here
我只想对第 "AA 331"
行和 "AA 1021"
行之后的最小整数之后的 "informations" 执行操作,而不是 "AA 332"
行之后,"AA 1022"
和 "AA 1023"
。
P.s这只是一个大文件的示例数据
下面的代码我尝试解析文本文件并获取列表 "list1" 中 "AA" 之后的整数,在第二个函数中我将它们分组以获得 [=31 中的最小值=].这将 return 整数,例如 [331,1021,...]。所以我想提取 "AA 331" 之后的行并执行操作,但我不知道如何继续。
from itertools import groupby
def getlineindex(textfile):
with open(textfile) as infile:
list1 = []
for line in infile :
if line.startswith("AA"):
intid = line[3:]
list1.append(intid)
return list1
def minimalinteger(list1):
list2 = []
for k,v in groupby(list1,key=lambda x: x//10):
minimalint = min(v)
list2.append(minimalint)
return list2
list2 包含 "AA" [331,1021,..]
之后的最小整数
您可以使用类似的东西:
import re
matcher = re.compile("AA ([\d]+)")
already_was = []
good_block = False
with open(filename) as f:
for line in f:
m = matcher.match(line)
if m:
v = int(m.groups(0)) / 10
else:
v = None
if m and v not in already_was:
good_block = True
already_was.append(m)
if m and v in already_was:
good_block = False
if not m and good_block:
do_action()
这些代码仅在组中的第一个值是最小值时才有效。
好的,这是我的解决方案。在高层次上,我逐行查看 AA 行以了解我何时找到数据块的 start/end,并查看我所谓的 运行 编号以了解是否找到我们应该处理下一个块。然后,我有一个处理任何给定块的子例程,基本上读取所有相关行并在需要时处理它们。该子例程用于监视 next AA 行,以便知道它何时完成。
import re
runIdRegex = re.compile(r'AA (\d+)')
def processFile(fileHandle):
lastNumber = None # Last run number, necessary so we know if there's been a gap or if we're in a new block of ten.
line = fileHandle.next()
while line is not None: # None is being used as a special value indicating we've hit the end of the file.
processData = False
match = runIdRegex.match(line)
if match:
runNumber = int(match.group(1))
if lastNumber == None:
# Startup/first iteration
processData = True
elif runNumber - lastNumber == 1:
# Continuation, see if the tenths are the same.
lastNumberTens = lastNumber / 10
runNumberTens = runNumber / 10
if lastNumberTens != runNumberTens:
processData = True
else:
processData = True
# Always remember where we were.
lastNumber = runNumber
# And grab and process data.
line = dataBlock(fileHandle, process=processData)
else:
try:
line = fileHandle.next()
except StopIteration:
line = None
def dataBlock(fileHandle, process=False):
runData = []
try:
line = fileHandle.next()
match = runIdRegex.match(line)
while not match:
runData.append(line)
line = fileHandle.next()
match = runIdRegex.match(line)
except StopIteration:
# Hit end of file
line = None
if process:
# Data processing call here
# processData(runData)
pass
# Return line so we don't lose it!
return line
给你的一些笔记。首先,我同意吉米连的说法,你应该使用正则表达式来匹配AA线。
其次,我们谈到的关于何时应该处理数据的逻辑在processFile中。特别是这些行:
processData = False
match = runIdRegex.match(line)
if match:
runNumber = int(match.group(1))
if lastNumber == None:
# Startup/first iteration
processData = True
elif runNumber - lastNumber == 1:
# Continuation, see if the tenths are the same.
lastNumberTens = lastNumber / 10
runNumberTens = runNumber / 10
if lastNumberTens != runNumberTens:
processData = True
else:
processData = True
我假设我们不想处理数据,然后确定我们何时处理。从逻辑上讲,您可以执行相反的操作并假设您想要处理数据,然后确定何时不需要。接下来,我们需要存储 last 运行 的值,以便知道我们是否需要处理此 运行 的数据。 (并注意第一个 运行 边缘情况)我们知道我们想要在序列被破坏时处理数据(两个 运行 之间的差异大于 1),这是由 else 处理的陈述。我们还知道我们想要在序列递增十位数字时处理数据,这是由我的整数除以 10 来处理的。
第三,注意来自 dataBlock 的 return 数据。如果不这样做,您将丢失导致 dataBlock 停止迭代的 AA 行,而 processFile 需要该行才能知道是否应处理下一个数据块。
最后,我选择使用 fileHandle.next() 和异常处理来确定何时到达文件末尾。但不要认为这是唯一的方法。 :)
如果您有任何问题,请在评论中告诉我。
我有一个文本文件,其中包含这样的数据
AA 331
line1 ...
line2 ...
% information here
AA 332
line1 ...
line2 ...
line3 ...
%information here
AA 1021
line1 ...
line2 ...
% information here
AA 1022
line1 ...
% information here
AA 1023
line1 ...
line2 ...
% information here
我只想对第 "AA 331"
行和 "AA 1021"
行之后的最小整数之后的 "informations" 执行操作,而不是 "AA 332"
行之后,"AA 1022"
和 "AA 1023"
。
P.s这只是一个大文件的示例数据
下面的代码我尝试解析文本文件并获取列表 "list1" 中 "AA" 之后的整数,在第二个函数中我将它们分组以获得 [=31 中的最小值=].这将 return 整数,例如 [331,1021,...]。所以我想提取 "AA 331" 之后的行并执行操作,但我不知道如何继续。
from itertools import groupby
def getlineindex(textfile):
with open(textfile) as infile:
list1 = []
for line in infile :
if line.startswith("AA"):
intid = line[3:]
list1.append(intid)
return list1
def minimalinteger(list1):
list2 = []
for k,v in groupby(list1,key=lambda x: x//10):
minimalint = min(v)
list2.append(minimalint)
return list2
list2 包含 "AA" [331,1021,..]
之后的最小整数您可以使用类似的东西:
import re
matcher = re.compile("AA ([\d]+)")
already_was = []
good_block = False
with open(filename) as f:
for line in f:
m = matcher.match(line)
if m:
v = int(m.groups(0)) / 10
else:
v = None
if m and v not in already_was:
good_block = True
already_was.append(m)
if m and v in already_was:
good_block = False
if not m and good_block:
do_action()
这些代码仅在组中的第一个值是最小值时才有效。
好的,这是我的解决方案。在高层次上,我逐行查看 AA 行以了解我何时找到数据块的 start/end,并查看我所谓的 运行 编号以了解是否找到我们应该处理下一个块。然后,我有一个处理任何给定块的子例程,基本上读取所有相关行并在需要时处理它们。该子例程用于监视 next AA 行,以便知道它何时完成。
import re
runIdRegex = re.compile(r'AA (\d+)')
def processFile(fileHandle):
lastNumber = None # Last run number, necessary so we know if there's been a gap or if we're in a new block of ten.
line = fileHandle.next()
while line is not None: # None is being used as a special value indicating we've hit the end of the file.
processData = False
match = runIdRegex.match(line)
if match:
runNumber = int(match.group(1))
if lastNumber == None:
# Startup/first iteration
processData = True
elif runNumber - lastNumber == 1:
# Continuation, see if the tenths are the same.
lastNumberTens = lastNumber / 10
runNumberTens = runNumber / 10
if lastNumberTens != runNumberTens:
processData = True
else:
processData = True
# Always remember where we were.
lastNumber = runNumber
# And grab and process data.
line = dataBlock(fileHandle, process=processData)
else:
try:
line = fileHandle.next()
except StopIteration:
line = None
def dataBlock(fileHandle, process=False):
runData = []
try:
line = fileHandle.next()
match = runIdRegex.match(line)
while not match:
runData.append(line)
line = fileHandle.next()
match = runIdRegex.match(line)
except StopIteration:
# Hit end of file
line = None
if process:
# Data processing call here
# processData(runData)
pass
# Return line so we don't lose it!
return line
给你的一些笔记。首先,我同意吉米连的说法,你应该使用正则表达式来匹配AA线。
其次,我们谈到的关于何时应该处理数据的逻辑在processFile中。特别是这些行:
processData = False
match = runIdRegex.match(line)
if match:
runNumber = int(match.group(1))
if lastNumber == None:
# Startup/first iteration
processData = True
elif runNumber - lastNumber == 1:
# Continuation, see if the tenths are the same.
lastNumberTens = lastNumber / 10
runNumberTens = runNumber / 10
if lastNumberTens != runNumberTens:
processData = True
else:
processData = True
我假设我们不想处理数据,然后确定我们何时处理。从逻辑上讲,您可以执行相反的操作并假设您想要处理数据,然后确定何时不需要。接下来,我们需要存储 last 运行 的值,以便知道我们是否需要处理此 运行 的数据。 (并注意第一个 运行 边缘情况)我们知道我们想要在序列被破坏时处理数据(两个 运行 之间的差异大于 1),这是由 else 处理的陈述。我们还知道我们想要在序列递增十位数字时处理数据,这是由我的整数除以 10 来处理的。
第三,注意来自 dataBlock 的 return 数据。如果不这样做,您将丢失导致 dataBlock 停止迭代的 AA 行,而 processFile 需要该行才能知道是否应处理下一个数据块。
最后,我选择使用 fileHandle.next() 和异常处理来确定何时到达文件末尾。但不要认为这是唯一的方法。 :)
如果您有任何问题,请在评论中告诉我。