【问题标题】:Insert number in a sorted list of tuples based on their 3rd number根据第 3 个数字在已排序的元组列表中插入数字
【发布时间】:2021-11-03 02:15:46
【问题描述】:

假设我有一个列表 A,当我插入元组 B 时,我得到了列表 C。 列表 A 是基于每个元组的第三个数字的排序列表

简而言之:如何将这个元组插入到列表 A 中,同时保持列表根据第三个值排序。

INSERT TO NOT SORT 这不是同一个问题 How to sort a list/tuple of lists/tuples by the element at a given index?

因为对列表进行排序实在是太慢了。

A = [(1, 2, 1),(1, 2, 2),(1, 2, 3),(1, 2, 5)]

insert --> B: (1, 2, 4)

C = [(1, 2, 1),(1, 2, 2),(1, 2, 3),(1, 2, 4),(1, 2, 5)]

【问题讨论】:

  • 我不知道是谁删除了我的问题,但这不是同一个问题。 stackoverflow.com/questions/3121979/…
  • 哦。嗯,有stackoverflow.com/questions/27672494/…。不幸的是,标准库不支持这一点。但是请记住,即使您可以比这更快地找到插入点,插入 list 也是 O(N)。以这种方式迭代构建列表将是 O(N^2),而一次放入所有内容并排序一次是 O(N lg N)。如果您需要有效地进行重复更新,则需要一种不同的数据结构,您必须自己创建或从第三方库获取。
  • 另外,如果你确实想插入到排序位置而不是“在末尾添加”+“排序后”方法,那么实现一个Binary Tree,其中val是你的元组.或者将元组存储为 val 并维护一个单独的“键”,该键始终分配给元组的第三项。但是,您需要实现自己的 to_list() 方法(或覆盖 __iter__ 并执行 list(tree))以获得树的列表版本。为什么排序很慢?为什么重复插入+排序优于所有插入和一种排序?显示到目前为止您尝试过的内容(代码)

标签: python list sorting insert tuples


【解决方案1】:

有效的方法是使用类似于 bisect 的东西。不幸的是,我认为该包的原始实现不可行,但此版本支持关键参数:https://github.com/python/cpython/blob/main/Lib/bisect.py

def bisect_left(a, x, lo=0, hi=None, *, key=None):
    """Return the index where to insert item x in list a, assuming a is sorted.
    The return value i is such that all e in a[:i] have e < x, and all e in
    a[i:] have e >= x.  So if x already appears in the list, a.insert(i, x) will
    insert just before the leftmost x already there.
    Optional args lo (default 0) and hi (default len(a)) bound the
    slice of a to be searched.
    """

    if lo < 0:
        raise ValueError('lo must be non-negative')
    if hi is None:
        hi = len(a)
    # Note, the comparison uses "<" to match the
    # __lt__() logic in list.sort() and in heapq.
    if key is None:
        while lo < hi:
            mid = (lo + hi) // 2
            if a[mid] < x:
                lo = mid + 1
            else:
                hi = mid
    else:
        while lo < hi:
            mid = (lo + hi) // 2
            if key(a[mid]) < x:
                lo = mid + 1
            else:
                hi = mid
    return lo

那么你可以简单地调用

C = A.copy()
C.insert(bisect_left(A, B, key=lambda tup: tup[2]), B)

【讨论】:

  • 在我的情况下如何调用这个函数? wat is lo en hi en * 然后我只做 key 2 (index2)
  • 编辑了以前的答案以包括这个
  • 我试过了,但报错:TypeError: insert() takes no keyword arguments I did this queu.insert(bisect_left(queu, (position[0], position[1], mazevalues[position[0]][position[1]])), (position[0], position[1], mazevalues[position[0]][position[1]]), key=lambda tup: tup[2])
  • 将其更改为C.insert(bisect_left(A, B[2], key=lambda tup: tup[2]), B) 后,它起作用了。谢谢你
猜你喜欢
  • 2021-02-11
  • 2011-06-30
  • 2019-09-27
  • 1970-01-01
  • 2023-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多