这些天我一直在操纵大量的文本文件。有时我需要删除行。 我的做法如下:
f=open('txt','r').readlines()
list=[]
for line in f:
if blablablabla:
list.append(line)
我知道对于大文件,.readlines()是速率限制步骤,但是.append()步骤呢?在readlines之后追加会花费多少额外的时间吗? 如果是这样,也许我应该找到直接删除我不想要的行的方法,而不是追加我想要的行。
THX
答案 0 :(得分:5)
如果您以后要过滤它,为什么要使用readlines()
读取整个文件?只需迭代它就可以保存想要保留的行。您可以使用列表推导将其减少到几行:
with open('txt', 'r') as f:
myList = [ line for line in f if blablablabla ]
答案 1 :(得分:2)
作为一般提示,请执行此操作,在迭代之前无需先读取完整文件...
with open('txt') as fd:
for line in fd:
if blablabla:
my_list.append(line)
并且不要调用列表“列表”......
答案 2 :(得分:1)
你应该使用列表理解,就像杰夫的回答一样。根据您处理数据的方式,您可以使用生成器表达式。
回答有关append()
的问题Python列表最后预先分配了一些额外的空间。这意味着追加非常快 - 直到你用完预分配的空间。无论何时扩展列表,都会分配一个新的内存块,并将所有引用复制到它。随着列表的增长,额外预分配空间的大小也会增加。这样做是为了使追加摊销O(1)。即追加的平均时间是快速且恒定的
答案 3 :(得分:1)
在这篇文章中,我尝试解释列表的工作方式以及为什么追加不是非常昂贵的。我还在底部发布了一个可用于删除行的解决方案。
Python列表的结构就像一个节点网络:
>>> class ListItem:
def __init__(self, value, next=None):
self.value = value
self.next = next
def __repr__(self):
return "Item: %s"%self.value
>>> ListItem("a", ListItem("b", ListItem("c")))
Item: a
>>> mylist = ListItem("a", ListItem("b", ListItem("c")))
>>> mylist.next.next
Item: c
因此,追加基本上就是这样:
ListItem(mynewvalue, oldlistitem)
附加没有太多开销,但另一方面insert()
要求您重建整个列表,因此需要更多时间。
>>> from timeit import timeit
>>> timeit('a=[]\nfor i in range(100): a.append(i)', number=1000)
0.03651859015577941
>>> timeit('a=[]\nfor i in range(100): a.insert(0, i)', number=1000)
0.047090002177625934
>>> timeit('a=[]\nfor i in range(100): a.append(i)', number=10000)
0.18015429656996673
>>> timeit('a=[]\nfor i in range(100): a.insert(0, i)', number=10000)
0.35550057300308424
如您所见,插入速度要慢得多。如果我是你,我只需消除你不需要的行,立即写回来。
with open("large.txt", "r") as fin:
with open("large.txt", "w") as f:
for line in fin:
if myfancyconditionismet:
# write the line to the file again
f.write(line + "\n")
# otherwise it is gone
有我的解释和解决方案。
-Sunjay03
答案 4 :(得分:0)
也许你想把它全部拉进内存然后对它进行操作。也许一次操作一行更有意义。从你的解释中可以看出哪个更好。
无论如何,无论您采用哪种方法,这都是非常标准的代码:
# Pull one line into memory at a time
with open('txt','r') as f:
lineiter = (line for line in f if blablablabla)
for line in lineiter:
# Do stuff
# Read the whole file into memory then work on it
with open('txt','r') as f:
lineiter = (line for line in f if blablablabla)
mylines = [line for line in lineiter]
如果您选择前一条路线,我建议您阅读发电机。 Dave Beazley有一篇关于生成器的文章"Generator Tricks for Systems Programmers"。强烈推荐。