【问题标题】:Maintain a list sorted by multiple attributes?维护一个按多个属性排序的列表?
【发布时间】:2014-01-24 14:35:18
【问题描述】:
ss = [(0,'bb','jj'), (1,'aa','mm'), (2,'aa','kk'),(3,'bb','ee'),(4,'gg','ff')]

for x in ss:
    pp = <somthing>

使用 Python,是否可以从 ss 插入 pp 并维护 pp 按两个属性排序,比如说 第 2 位然后是第 3 位,以便获得以下结果(两个属性都升序):

pp = [(2, 'aa', 'kk'), (1, 'aa', 'mm'), (3, 'bb', 'ee'), (0, 'bb', 'jj'), (4, 'gg', 'ff')]

或者(两个属性都降序):

pp = [(4, 'gg', 'ff'), (0, 'bb', 'jj'), (3, 'bb', 'ee'), (1, 'aa', 'mm'), (2, 'aa', 'kk')]

我不想在已经完成工作的循环之后使用以下两个语句:

pp = sorted(ss, key = operator.itemgetter(1, 2))
pp = sorted(ss, key = operator.itemgetter(1, 2), reverse=True)

因为我正在处理一个很长的列表,并且我已经有了想要重用于排序的循环。

【问题讨论】:

  • 看看bisect 模块。
  • 将新元素附加到循环中的pp(或只写pp.extend(ss)),然后使用与sorted 调用相同的参数调用pp.sort去做。感谢 Timsort,这是在 Python 中维护排序列表的有效方法。
  • 嗯,刚刚发现你没有保留pp的原始内容。然后忽略关于extend的部分。我不明白你为什么不想使用sorted 行。无论列表的大小如何,sorted 都是一种创建排序副本的有效方法。通过将每个元素重复插入正确的位置,您将不会获得更好的性能。这称为“插入排序”,如果它是一个好的排序算法,那么sorted 可能会使用它。对于大型列表,这并不好。
  • 我会使用通过heapq 模块函数实现的优先级队列。但这需要额外的工作,因为您的排序标准并非微不足道。看看这个:docs.python.org/2/library/…

标签: python list sorting attributes


【解决方案1】:

您可以在每次插入时使用二分查找。

ss = [(0,'bb','jj'), (1,'aa','mm'), (2,'aa','kk'),(3,'bb','ee'),(4,'gg','ff')]

l = []

def insert_sort(l, e, compare):
    lo = 0
    hi = len(l)
    while lo < hi:
        mid = (lo+hi) / 2
        if compare(e, l[mid]):
            lo = mid + 1
        else: 
            hi = mid
    l.insert(lo, e)

ascend_list = []
descend_list = []

for i in ss:
    insert_sort(ascend_list, i, lambda x, y: x[1:] >= y[1:])

for i in ss:
    insert_sort(descend_list, i, lambda x, y: x[1:] < y[1:])

print ascend_list
print descend_list

【讨论】:

  • @falsetru 感谢您的建议。
猜你喜欢
  • 2012-12-09
  • 2011-05-13
  • 1970-01-01
  • 1970-01-01
  • 2011-01-25
  • 2019-09-19
  • 1970-01-01
相关资源
最近更新 更多