Python:最快的list.index()操作使用'是',而不是'=='(即通过引用)

时间:2011-12-06 16:37:26

标签: python list

问题:

在python中,list.index(a)将返回a == list[index]为真的任何索引。但我需要找到a is list[index]的索引,并尽快完成(速度至关重要)。我该怎么做?

背景:

也许我会以错误的方式编程。以防万一,这是我需要解决上述问题的问题:

我有一些文字,我必须能够非常快速地插入/删除字符。因此,我使用字符列表(大约一百万)而不是字符串。

此外,在索引处的任何给定插入/删除操作之后,我必须非常快地知道该索引之前有多少换行符。我试过list[0:index].count(newline),但速度很慢。所以我正在尝试使用上述问题的解决方案的第二种方法。

当然,根据定义,这种在每次操作后解决的方法可能太慢了。但考虑到每次插入/删除字符时索引和换行量都会发生变化,我无法想到维护信息的任何快速方法(用于查找,因此我不必每次都进行处理)。

编辑:

这是我迄今为止的解决方案。使用cProfile,我发现执行chars[0:index].count()的时间可能是1/50,但仍然不够快:

#Initialized once, and then maintained after every change.
chars = [['\n'],['a'],['b'],['\n'],.... ]
newlines = [newline for newline in chars if newline == ['\n']]

#called every time I need the count of newlines preceding 'index'
def newlinecount(index):

    #find closest preceding newline
    previousNewlineIndex = index
    while not chars[previousNewlineIndex ] == ['\n']:
        previousNewlineIndex -= 1
    previousNewline = chars[previousNewlineIndex]

    #find position of 'previousNewline' in 'newlines', and thus newlinecount
    for count, newline in enumerate(newlines):
        if newline is previousNewline:
            return count + 1 #(add 1 because 'count' starts from 0)

谢谢!

3 个答案:

答案 0 :(得分:2)

  

在python中,list.index(a)将返回a == list[index]为真的任何索引。但我需要找到a is list[index]的索引,并尽可能快地完成(速度至关重要)。

即使list.index()以这种方式工作,你也不会从中受益。由于Python中没有字符类型,因此应将字符存储为整数,而不是单字符字符串。对==is的整数进行比较。

  

我有一些文字,我必须能够非常快速地插入/删除字符。因此,我使用一个字符列表(大约一百万)而不是一个字符串。

在列表中存储字符是一种允许快速插入和删除的方法。 Python列表是动态数组,而不是链表,因此添加或删除项目为O(n)。例如,如果您要删除5中的range(10),则69的项目需要向左移动一个位置。

  

此外,在索引处的任何给定插入/删除操作之后,我必须非常快地知道该索引之前有多少换行符。

我建议您将换行符的索引保存在单独的数据结构中,并在每次添加或删除换行符时更新它。否则,您将始终必须扫描整个列表到当前点。

由于Python是一种非常高级的语言,我怀疑你可以在纯Python中为你的问题获得非常好的性能。

答案 1 :(得分:1)

不确定我是否正确遵循了,但将您的文字视为一系列呢?

如果您将1Mb文本存储为字符串列表(每行一个字符串),您将非常快速地处理插入/替换(字符串将很短)并且您可以使用列表的索引来跟踪多少换行符位于文本的给定点之前/之后。

这对我有什么帮助,还是我误解了你想要做的事情?

答案 2 :(得分:0)

我认为,您可能需要的是维护两个独立的数据结构:

  • char_list:字符列表本身。对此的操作将是
  • index_list:另一个排序列表,其中包含换行符的位置(索引)

您的插入和删除操作将对两种数据结构都有效。 插入/删除char时,将增加/减少index_list中的相应元素。之后index_list.index(new_char_index)将返回插入/删除的字符之前的换行符数