0

我有以下文本文件:

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]
4

6 回答 6

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 替换为要附加到的列表。

于 2012-08-24T21:35:08.593 回答
0

编辑:在迭代时删除项目可能不是一个好主意,请参阅:在迭代时从列表中删除项目

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这就是你想要的。

于 2012-08-24T21:31:14.670 回答
0

代码有一些问题;例如,data_list甚至没有定义。如果它是 a list,则不能del从中获取元素;你只能pop。然后你在 ; 上同时使用enumerate和直接索引访问data。也不readlines需要。

我建议避免将所有行都保存在内存中,这里并不是真的需要。也许尝试使用类似(未经测试)的东西:

with open('infile.txt') as fin, open('outfile.txt', 'w') as fout:
   for line in fin:
       if line.startswith('NUM,') and line.split(',')[1] not in wanted:
           for _ in range(4):
               fin.next()
       else:
           fout.write(line)
于 2012-08-24T21:36:00.840 回答
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
于 2012-08-24T21:36:51.300 回答
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])
于 2012-08-24T21:59:31.380 回答
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)
于 2012-08-25T00:31:35.833 回答