我有以下文本文件:
This is my text file
NUM,123
FRUIT
DRINK
FOOD,BACON
CAR
NUM,456
FRUIT
DRINK
FOOD,BURGER
CAR
NUM,789
FRUIT
DRINK
FOOD,SAUSAGE
CAR
NUM,012
FRUIT
DRINK
FOOD,MEATBALL
CAR
我有以下名为'通缉'的名单:
['123', '789']
我要做的是,如果NUM之后的数字不在名为“想要”的列表中,那么该行以及它下面的4行将被删除。因此输出文件将如下所示:
This is my text file
NUM,123
FRUIT
DRINK
FOOD,BACON
CAR
NUM,789
FRUIT
DRINK
FOOD,SAUSAGE
CAR
到目前为止我的代码是:
infile = open("inputfile.txt",'r')
data = infile.readlines()
for beginning_line, ube_line in enumerate(data):
UNIT = data[beginning_line].split(',')[1]
if UNIT not in wanted:
del data_list[beginning_line:beginning_line+4]
答案 0 :(得分:4)
在循环播放列表时,不应修改列表。
你可以尝试的是在需要时只需在文件对象上推进迭代器:
wanted = set(['123', '789'])
with open("inputfile.txt",'r') as infile, open("outfile.txt",'w') as outfile:
for line in infile:
if line.startswith('NUM,'):
UNIT = line.strip().split(',')[1]
if UNIT not in wanted:
for _ in xrange(4):
infile.next()
continue
outfile.write(line)
并使用一套。不断检查会员资格会更快。
此方法不会让您立即读取整个文件以便以列表形式处理它。它逐行,从文件读取,推进和写入新文件。如果需要,可以使用要附加的列表替换outfile。
答案 1 :(得分:0)
编辑:在迭代时删除项目可能不是一个好主意,请参阅:Remove items from a list while iterating
infile = open("inputfile.txt",'r')
data = infile.readlines()
SKIP_LINES = 4
skip_until = False
result_data = []
for current_line, line in enumerate(data):
if skip_until and skip_until < current_line:
continue
try:
_, num = line.split(',')
except ValueError:
pass
else:
if num not in wanted:
skip_until = current_line + SKIP_LINES
else:
result_data.append(line)
... result_data
就是你想要的。
答案 2 :(得分:0)
代码存在一些问题;例如,data_list
甚至没有定义。如果它是list
,则您不能del
元素;你只能pop
。然后在enumerate
上使用data
和直接索引访问; <{1}}也不需要。
我建议避免将所有行保留在内存中,这里不需要它。也许尝试类似(未经测试):
readlines
答案 3 :(得分:0)
import re
# find the lines that match NUM,XYZ
nums = re.compile('NUM,(?:' + '|'.join(['456','012']) + ")")
# find the three lines after a nums match
line_matches = breaks = re.compile('.*\n.*\n.*\n')
keeper = ''
for line in nums.finditer(data):
keeper += breaks.findall( data[line.start():] )[0]
给定字符串的结果是
NUM,456
FRUIT
DRINK
FOOD,BURGER
NUM,012
FRUIT
DRINK
FOOD,MEATBALL
答案 4 :(得分:0)
如果您不介意构建列表,并且如果您的"NUM"
行每5行另外一行,您可能需要尝试:
keep = []
for (i, v) in enumerate(lines[::5]):
(num, current) = v.split(",")
if current in wanted:
keep.extend(lines[i*5:i*5+5])
答案 5 :(得分:0)
不要试图在构建列表和从循环中删除内容时考虑到这一点。那种方式导致了疯狂。
直接编写输出文件要容易得多。循环输入文件的行,每次都决定是否将其写入输出。
另外,为了避免每行都没有逗号这一事实的困难,请尝试使用.partition
来分割行。这将总是返回3项:当有逗号时,你得到(在第一个逗号之前,逗号,在逗号之后);否则,你得到(整个事情,空字符串,空字符串)。所以你可以使用那里的最后一项,因为wanted
无论如何都不会包含空字符串。
skip_counter = 0
for line in infile:
if line.partition(',')[2] not in wanted:
skip_counter = 5
if skip_counter:
skip_counter -= 1
else:
outfile.write(line)