在python中删除某行文本文件

时间:2012-08-24 21:14:16

标签: python text line

我有以下文本文件:

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]

6 个答案:

答案 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)