开发者

Python list.remove() seems to malfunction

fileHandle = open(filedir, 'r')
content = fileHandle.read().split('\n')
for e in content:
    if (e == '' or (e[0] != r"@"):
        content.remove(e)
fileHandle.close()

So, what I'm trying to do here is open a file with some text and split it into lines, and then remove those lines that doesn开发者_开发百科't start with @. But instead, at some point it just doesnt take off more lines and some without the '@' end in the content var. Why?


Never remove items of a list while iterating over it.

Why not just do the following:

with open(filedir) as f:
    lines = [line.rstrip("\r\n") for line in f if line.startswith("@")]


Don't modify a container while you're iterating over it.

You're over-complicating this in many ways: you don't need to close the file explicitly (use a with -block); you don't need to use a "raw string" to specify '@'; you don't need to invent "starts with"; you don't need to split the file into lines yourself (just iterating over the file yields the data a line at a time) and you don't need to write your own loop.

What you want is a list of the lines in the file that start with '@'. So, ask for that directly:

with open(filedir, 'r') as fileHandle:
  content = [line for line in fileHandle if line.startswith('@')]


Because you're screwing with the list as you're iterating over it. Plus, you should be iterating over the file to get it line by line. Plus, you're not even writing the results out.

with open(filedir, 'r') as fileHandle:
  with open(outputfile, 'w') as outputHandle:
    for line in fileHandle:
      if not line or line.startswith('@'):
        continue
    outputHandle.write(line)


You shouldn't modifying what you're iterating over. I've made some changes to your code and reposted it here with comments.

fileHandle = open(filedir, 'r')
content = (x.strip() for x in fileHandle.readlines()) # Get all the lines and use a genexp to strip out the spaces. 
for e in content[:]: # Python idiom for "copy of a list"
    if (e == '' or (e[0] != r"@"):
        content.remove(e)
fileHandle.close()

This is just to illustrate the [:] operator. I'd still recommend Ignacio's solution over this.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜