代码之家  ›  专栏  ›  技术社区  ›  G_T

展开元组列表[重复]

  •  1
  • G_T  · 技术社区  · 2 年前

    我有一个很大的元组列表(2000万到3000万个条目)。每个子元组有三条信息 (start, end, value) 并且被认为仅表示序列中的一个位置。然而,如果相邻位置的值相同,则生成该数据的程序会将相邻位置的一些值连接起来。因此,它们看起来是这样的:

    [..., (71, 72, -0.2998250126838684),
          (72, 73, -0.2858070135116577),
          (73, 74, -0.29049500823020935),
          (74, 75, -0.3044680058956146),
          (75, 76, -0.28386199474334717),
          (76, 80, -0.27730199694633484), # PROBLEM: end - start > 1
          (80, 81, -0.2726449966430664),
          (81, 82, -0.26151400804519653),
          (82, 84, -0.2679719924926758),  # PROBLEM: end - start > 1
          (84, 85, -0.24273300170898438),
          (85, 86, -0.23799900710582733),
          (86, 87, -0.24745100736618042),
          (87, 88, -0.2568419873714447),
          (88, 89, -0.2585819959640503), ...]
    

    为了解决这个问题,我想在列表中创建新的条目,将这些表示多个位置的元组分隔成只表示一个位置的新元组。 因此,我希望得到这样的输出:

    (..., (71, 72, -0.2998250126838684),
          (72, 73, -0.2858070135116577),
          (73, 74, -0.29049500823020935),
          (74, 75, -0.3044680058956146),
          (75, 76, -0.28386199474334717),
          (76, 77, -0.27730199694633484), # New
          (77, 78, -0.27730199694633484), # New
          (78, 79, -0.27730199694633484), # New
          (79, 80, -0.27730199694633484), # New
          (80, 81, -0.2726449966430664),
          (81, 82, -0.26151400804519653),
          (82, 83, -0.2679719924926758),  # New
          (83, 84, -0.2679719924926758),  # New
          (84, 85, -0.24273300170898438),
          (85, 86, -0.23799900710582733),
          (86, 87, -0.24745100736618042),
          (87, 88, -0.2568419873714447),
          (88, 89, -0.2585819959640503), ...)
    

    为此,使用我的元组列表 bwList 我已经做了以下工作:

    replacementTuple = ()
    
    for t in bwList:
        if t[1] - t[0] == 1:
            replacementTuple = replacementTuple + (t,)
        else:
            numNewTuples = t[1] - t[0]
            st, ed = range(t[0], t[1]), range(t[0] + 1, t[1] + 1)
            for m in range(numNewTuples):
                replacementTuple = replacementTuple + ((st[m], ed[m], t[2]) ,) 
    

    这里的输出是元组的元组,而不是列表。无论哪种方式,我都不太介意。

    这种方法看似有效,但速度非常慢!

    有没有办法加快速度?

    2 回复  |  直到 2 年前
        1
  •  0
  •   ShadowRanger    2 年前

    非常简单(而且可能更快,主要是由于摊销 O(1) appends)将构建 list 扩展每个 tuple (可能相同 元组 仅一次,但没有特殊套管):

    replacement_list = [(newstart, newstart+1, value)
                        for start, end, value in bwList
                        for newstart in range(start, end)]
    

    您可以将其转换为 元组 如果你喜欢的话,在最后,但将其构建为 列表 首先会省去很多麻烦。

        2
  •  0
  •   Barmar    2 年前

    使用列表而不是元组作为结果。然后,您可以在适当的位置对其进行附加,而不是每次添加时都制作元组的副本,这会使您的算法为O(n^2)。

    你不需要 if 语句——在这种情况下 end = start+1 只是一个限制情况,循环将正确处理它。

    replacementList = []
    
    for start, end, value in bwList:
        for i in range(start, end):
            replacementList.append((i, i+1, value))
    

    您也可以使用生成器来构造元组。

    replacementTuple = tuple((i, i+1, value) for start, end, value in bwList for i in range(start, end))