2015-04-03 258 views
1

我试图删除38行文本,在Python中的.txt文件中遇到特定短语,同时仍然打印文本的其余部分。不识别Python中的循环变量

我目前拥有的代码是

with open('text_file.txt','r') as f: 
lines = f.readlines() 
for line in lines: 
    if "certain_phrase" in line: 
     for num in range(38): 
      del line 
    else: 
     print(line,end='') 

不过,我不断收到以下错误:

Traceback (most recent call last): 
    File "C:\<location of file>\python_program.py", line 6, in <module> 
    del line 
NameError: name 'line' is not defined 

没有人有任何建议或线索,为什么它不能识别“行”一旦我把它放在下面的for循环里面?另外,有没有更好的方法来执行这种程序?

+2

即使没有错误,此代码也不会执行你想要的操作 – 2015-04-03 15:09:20

+0

它不知道变量'line'在你的'for循环中num的第二次迭代,因为你刚删除它在以前的迭代中并没有在 – 2015-04-03 15:11:05

+0

之间重新定义它首先建议:读取文件时不需要第2行(由于将整个文件存储在内存中,而不是逐行读取,这会浪费内存)=>在f' – 2015-04-03 15:15:52

回答

3

您将需要从列表中删除,你不能del行了,最简单的方法是写一个临时文件,如果要修改的文件复制后,如果您只想打印无视38符合打印代替写:

with open('in.txt','r') as f,open('temp.txt','w') as temp: 
    for line in f: 
     if "phrase" in line: 
      for i in range(38): 
       next(f) # skip 38 lines 
     else: 
      temp.write(line) 

然后使用shutil移动文件:

import shutil 

shutil.move("temp.txt","in.txt") 

你也可以使用一个NamedTemporaryFile

from tempfile import NamedTemporaryFile 

with open('file.txt','r') as f, NamedTemporaryFile(dir=".",delete=False) as temp: 
    for line in f: 
     if "phrase" in line: 
      for i in range(38): 
       next(f) 
     else: 
      temp.write(line) 

import shutil 
shutil.move(temp.name,"file.txt") 

我看到的唯一潜在的问题是,如果这句话是在38线被忽略的一个,你也应该从那里取出接下来的38行。

To ignore until a second phrase, keep looping in the inner loop until you find the second phrase then break: 

with open('in.txt','r') as f, NamedTemporaryFile(dir=".", delete=False) as temp: 
    for line in f: 
     if "phrase" in line: 
      for _line in f: 
       if "phrase2" in _line: 
        break 
     else: 
      temp.write(line) 
+0

这工作非常好!非常感谢!非常有用的知道! – codycrossley 2015-04-03 15:34:30

+0

@codycrossley,不用担心,不客气。 – 2015-04-03 15:35:12

+0

难道你不能使用while循环,并重置计数器,如果该短语是在38忽略行? – 2015-04-03 15:39:49

0

del line实际上删除了变量line,这意味着当您第二次尝试时,它不起作用,因为line不再被定义。您可以遍历索引来查找线,突破,然后删除下一个38行:

with open('text_file.txt','r') as f: 
lines = f.readlines() 
for i in range(len(lines)): 
    if "certain_phrase" in lines[i]: 
     break 
    else: 
     print(line,end='') 
for num in range(38): 
    del lines[i] 
0
​​
+0

我很确定这不会执行提问者想要的操作......这会删除包含“certain_phrase”的前38行,而不是直到它在一行中找到“certain_phrase”,然后删除(或真正跳过)接下来的38行 – Foon 2015-04-03 17:01:37

+0

@Foon是的,我误解了这个问题。固定。 – Alan 2015-04-03 17:54:51

1

,而不是试图从文件中删除线,编写基于旧的一个新文件。以下使用__next__()跳过发生器产生的line

with open('text_file.txt','r') as f, open('text_file_mod.txt', 'w') as w: 
    for line in f: 
     w.write(line) 
     if "certain_phrase" in line: 
      for num in range(38): # skip 38 lines 
       next(f) 

如果你从交互式解释这样做,可以防止它通过next(f)w.write(line)结果保存到变量吐出返回的值。