Python .append()是否耗时?

Python .append()是否耗时?,python,append,readlines,Python,Append,Readlines,这些天我一直在处理巨大的文本文件。有时我需要删除行。 我的做法如下: f=open('txt','r').readlines() list=[] for line in f: if blablablabla: list.append(line) 我知道对于大文件,.readlines是速率限制步骤,但是.append步骤呢?在读取行之后追加会花费很多额外的时间吗? 如果是这样,也许我应该想办法直接删除我不想要的行,而不是附加我想要的行 thx如果以后要过滤整个文件,为什么

这些天我一直在处理巨大的文本文件。有时我需要删除行。 我的做法如下:

f=open('txt','r').readlines()
list=[]
for line in f:
    if blablablabla:
       list.append(line)
我知道对于大文件,.readlines是速率限制步骤,但是.append步骤呢?在读取行之后追加会花费很多额外的时间吗? 如果是这样,也许我应该想办法直接删除我不想要的行,而不是附加我想要的行


thx

如果以后要过滤整个文件,为什么要使用readlines读取整个文件?只需在其中迭代,保存您想要保留的行。您可以使用列表理解将其缩减为几行:

with open('txt', 'r') as f:
    myList = [ line for line in f if blablablabla ]

如果以后要过滤整个文件,为什么要使用readlines读取整个文件?只需在其中迭代,保存您想要保留的行。您可以使用列表理解将其缩减为几行:

with open('txt', 'r') as f:
    myList = [ line for line in f if blablablabla ]

作为一般提示,请改为这样做,无需在迭代之前先读取完整的文件

with open('txt') as fd:
    for line in fd:
        if blablabla:
            my_list.append(line)

不要调用列表…

作为一般提示,而是这样做,在迭代之前无需先读取完整的文件

with open('txt') as fd:
    for line in fd:
        if blablabla:
            my_list.append(line)

不要叫列表…

你应该用列表理解代替杰夫的回答。根据需要处理数据的方式,您可以使用生成器表达式

回答您关于附加的问题


Python列表在末尾预先分配了一些额外的空间。这意味着追加速度非常快,直到预分配的空间用完为止。每当扩展列表时,都会分配一个新的内存块,并将所有引用复制到它。随着列表的增长,额外预分配空间的大小也随之增加。这样做是为了使追加摊销为O1。ie追加的平均时间是快速且恒定的

您应该使用列表理解,而不是Jeff的答案。根据需要处理数据的方式,您可以使用生成器表达式

回答您关于附加的问题


Python列表在末尾预先分配了一些额外的空间。这意味着追加速度非常快,直到预分配的空间用完为止。每当扩展列表时,都会分配一个新的内存块,并将所有引用复制到它。随着列表的增长,额外预分配空间的大小也随之增加。这样做是为了使追加摊销为O1。在这篇文章中,我试图解释列表的工作方式,以及为什么追加并不十分昂贵。我还在底部发布了一个解决方案,可以用来删除行

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
因此,append基本上就是这样:

ListItem(mynewvalue, oldlistitem)
Append没有太多开销,但另一方面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在这篇文章中,我试图解释列表的工作方式,以及为什么append不是很贵。我还在底部发布了一个解决方案,可以用来删除行

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
因此,append基本上就是这样:

ListItem(mynewvalue, oldlistitem)
Append没有太多开销,但另一方面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

也许你想把它全部放到内存中,然后对它进行操作。也许一次在一条线上操作更有意义。你的解释不清楚哪个更好

在任何情况下,无论您采用哪种方法,这里都有相当标准的代码:

# 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)有一篇关于发电机的很棒的文章,名为。强烈推荐。

也许您希望将其全部放入内存,然后对其进行操作。也许一次在一条线上操作更有意义。你的解释不清楚哪个更好

在任何情况下,无论您采用哪种方法,这里都有相当标准的代码:

# 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)有一篇关于发电机的很棒的文章,名为。强烈推荐。

阵列也不是一个很好的选择,尽管比列表更好,因为还有阵列模块。Ray也不是一个很好的选择,尽管比列表更好,因为还有阵列模块。Well,使用readlines,您已经将整个文件读取到列表中了。然后根据其内容创建另一个筛选列表。您不需要使用readlines预先处理整个文件,因此
最好不要使用它,或者更改算法,从列表中删除不需要的行。担心追加的速度是没有必要的,它真的不应该对代码的速度有任何影响。如果你真的想弄清它的底细,你应该对它进行分析,并了解自己。也许,这取决于文件的大小。列表理解很快。另外,您不会一次将整个文件加载到内存中,这样可以保持性能。@wang,即使没有一行被过滤掉,您至少已经保存了制作整个列表的额外副本。thx…但是“取决于大小”是什么意思?我的输入文件非常大,有50000000行……所以对于这样大的文件,列表理解速度会快得多吗?@wang:只要文件不是很大,使用readlines就可以了。5000万条线肯定非常大,所以你应该不惜一切代价避免它。您还没有提到这些行的具体用途,但是您可能希望避免将它们全部放在一个列表中。如果您打算最终将它们写回一个文件,那么最好按照sunjay的回答将它们写回一个文件,或者在循环文件时立即处理它们。好的,使用readlines,您已经将整个文件读取到一个列表中了。然后根据其内容创建另一个筛选列表。您不需要使用readlines预先处理整个文件,因此最好根本不使用它,或者更改算法以从列表中删除不需要的行。担心追加的速度是没有必要的,它真的不应该对代码的速度有任何影响。如果你真的想弄清它的底细,你应该对它进行分析,并了解自己。也许,这取决于文件的大小。列表理解很快。另外,您不会一次将整个文件加载到内存中,这样可以保持性能。@wang,即使没有一行被过滤掉,您至少已经保存了制作整个列表的额外副本。thx…但是“取决于大小”是什么意思?我的输入文件非常大,有50000000行……所以对于这样大的文件,列表理解速度会快得多吗?@wang:只要文件不是很大,使用readlines就可以了。5000万条线肯定非常大,所以你应该不惜一切代价避免它。您还没有提到这些行的具体用途,但是您可能希望避免将它们全部放在一个列表中。如果您打算最终将它们写回一个文件,那么最好按照sunjay的回答将它们写回一个文件,或者在循环文件时立即处理它们。我确信您对Python列表的解释是错误的。它们被实现为一个可调整大小的数组,而不是一个链表。您绘制的数据结构在索引方面的性能很差,例如somelist[43]。Append很快,因为数组末尾通常有空间放置另一个项目,而insert很慢,因为它需要将以下所有元素移动到一个位置,以便为插入的元素腾出空间。我确信您对Python列表的解释是错误的。它们被实现为一个可调整大小的数组,而不是一个链表。您绘制的数据结构在索引方面的性能很差,例如somelist[43]。Append是快速的,因为在数组的末尾通常有空间放置另一个项目;insert是缓慢的,因为它需要将以下所有元素移动到一个位置,以便为插入的元素腾出空间。