【问题标题】:Python data structure for a indexable list of string用于可索引字符串列表的 Python 数据结构
【发布时间】:2011-05-26 15:47:53
【问题描述】:

我得到了一个对象列表,这些对象看起来像字符串,但不是真正的字符串(想想 mmap 文件)。像这样:

x = [ "abc", "defgh", "ij" ]

我想要的是 x 可以直接索引,就​​像它是一个大字符串一样,即:

(x[4] == "e") is True

(当然我不想做 "".join(x) 这会合并所有字符串,因为在我的情况下读取字符串太昂贵了。记住它是 mmap 文件。)。

如果您遍历整个列表,这很容易,但它似乎是 O(n)。所以我通过创建这样一个列表更有效地实现了__getitem__

x = [ (0, "abc"), (3, "defgh"), (8, "ij") ]

因此,我可以在__getitem__ 中进行二进制搜索,以快速找到具有正确数据的元组,然后为其字符串编制索引。这很好用。

我看到了如何实现__setitem__,但它看起来很无聊,我想知道是否没有什么东西已经做到了。

更准确地说,这就是数据结构应该尊重__setitem__的方式:

>>> x = [ "abc", "defgh", "ij" ]
>>> x[2:10] = "12345678"
>>> x
[ "ab", "12345678", "j" ]

我对这样的数据结构实现、名称或任何提示有任何想法。

【问题讨论】:

  • "我当然不想做"".join(x) 会合并所有字符串?"为什么不? “在我的情况下,读取字符串太贵了”这与任何事情有什么关系?什么 - 确切地说 - 连接有问题?
  • 因为列表中的字符串并不是真正的字符串。它们是(某种)mmap'ed 文件。但它们就像字符串一样工作(它们实现了__getitem__)。
  • x[4] == e 因为__getitem__x 类(列表的子类)中被重载。
  • @Woot4Moo:如果您将所有字符串合并为一个,则“e”位于索引 4。
  • @jd_:“列表中的字符串并不是真正的字符串”。那么请修正问题以说明真正是什么。现在,这个问题具有误导性。

标签: python algorithm data-structures


【解决方案1】:

您所描述的是rope data structure 的一个特例。

很遗憾,我不知道有任何 Python 实现。

【讨论】:

【解决方案2】:

您已经重新创建了字典数据类型。

【讨论】:

  • 不完全是。在字典中,如果 i 不是其中一个子字符串的开头,则无法在位置 i 处轻松找到字符。
  • 并非每个键都直接对应于列表中的一个字符串。如果您的意思是它在概念上是一本字典,那也不是真的,因为在0len(op_s_object) s.t. 之间不可能没有iop_s_object[i] 没有价值。
  • op 的解释有些欠缺,比如他还没有解释 x[4] == e.他是否覆盖等于意味着包含:?
  • “我想要的是 x 可以直接索引,就​​像它是一个大字符串一样”——我认为这意味着他正在构建一个序列类型,即通过不同方式的字符串。
  • 为什么不直接使用已经有 O(1) 查找的字符数组。或者我忘记了它的 O(n)。
【解决方案3】:

那么您是否仍然希望能够处理第 n 个列表元素,例如找到 x.somemethod(2) == 'ij'? 如果不是,那么您的数据结构只是一个字符串,其中包含一些使其可变并从字符串列表中对其进行初始化的方法。

如果您确实希望能够做到,那么您的数据结构仍然是一个包含这些额外方法的字符串,以及另一个用于跟踪其元素来自的范围的元素,例如 x.camefrom(1) == (3, 7)

无论哪种方式,您似乎都想存储和操作一个字符串。

【讨论】:

  • 你错过了我写“我不想阅读字符串”的部分。如果我理解正确,创建从字符串列表初始化的字符串意味着读取所有字符串并复制它们。 :)
  • 我没有错过。我忽略了它,因为听起来你让事情变得比你需要的要困难得多,而没有解释为什么你想以艰难的方式去做。 :-)
【解决方案4】:

这可能是一个开始:

self._h = {0:"abc", 3:"defgh", 8:"ij"} #create _h and __len__ in __init__
self.__len__ = 10

def __getitem__(i):
    if i >= self.__len__:
        raise IndexError
    o=0
    while True:
        if i-o in self._h:
            return self._h[i-o][o]
        o+=1

改进包含可变性。

【讨论】:

    【解决方案5】:

    我不知道有什么可以满足您的要求。

    但是,如果您按照您所说的方式有效地实现了__getitem__,那么您已经有了将索引映射到您的元组字符串列表的代码。因此,您似乎可以重用那段代码——稍加重构——来实现__setitem__,它需要相同的信息来执行其功能。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多