在python中,如何创建一个按一个值排序并可由另一个值编制索引的集合

时间:2015-03-14 03:59:18

标签: python collections sorted indexed

我需要一个集合,我在其中插入[1,' b42b00d6-76c8-4d68-b22e-ff4653bb01c8']等项目。

它需要由第一个元素排序,但可以由第二个元素排序。

以下是我能想出的最好成绩。它有两个缺点:

  • 它不能使用相同的密钥来处理多个项目,因为它是a 字典。
  • 无法正确删除列表中的项目。

我的尝试:

from rbtree import rbtree

class Item(object):
    def __init__(self, value, id):
         self.value = value
         self.id = id

item1 = Item(1,'b42b00d6-76c8-4d68-b22e-ff4653bb01c8')
item2 = Item(2,'60eda62f-f05d-4134-9e92-9bb9a1f52daf')
item3 = Item(2,'77d9a028-bd4b-4634-b230-234f88ff010a')
item4 = Item(3,'7e7118cd-7145-41c8-8413-79670bdc81dc')

myList = rbtree()
myList[item2.value] = item2
myList[item1.value] = item1
myList[item3.value] = item3
myList[item4.value] = item4

# Correctly ordered by the first element
# But it's missing item2.

for k,v in myList.iteritems():
    print "%s %s" % (v.value, v.id)

# But I also need to index by the second element.
# So:

listIndexedBySecondElement = {}
listIndexedBySecondElement[item1.id] = item1
listIndexedBySecondElement[item2.id] = item2
listIndexedBySecondElement[item3.id] = item3
listIndexedBySecondElement[item4.id] = item4

item = listIndexedBySecondElement['7e7118cd-7145-41c8-8413-79670bdc81dc']
print item.value # correctly prints 3

# Now I need to delete an element.

del listIndexedBySecondElement['b42b00d6-76c8-4d68-b22e-ff4653bb01c8']
# But I also need to delete it from myList. How do I do that?

3 个答案:

答案 0 :(得分:1)

开始之前:

del listIndexedBySecondElement['b42b00d6-76c8-4d68-b22e-ff4653bb01c8']

抓住这个项目:

itm = listIndexedBySecondElement['b42b00d6-76c8-4d68-b22e-ff4653bb01c8']

现在您可以从以下两个位置删除它:

del listIndexedBySecondElement['b42b00d6-76c8-4d68-b22e-ff4653bb01c8']
del myList[itm.value]

至于“订单”部分 - 字典不是有序的数据结构,为此您必须实现其他内容。

答案 1 :(得分:0)

您可以改为使用id值词典:

mydict = {}
mydict['77d9a028-bd4b-4634-b230-234f88ff010a'] = 2
mydict['b42b00d6-76c8-4d68-b22e-ff4653bb01c8'] = 1
mydict['7e7118cd-7145-41c8-8413-79670bdc81dc'] = 3
mydict['60eda62f-f05d-4134-9e92-9bb9a1f52daf'] = 2

现在可以通过id索引字典。您可以按进行排序和打印,如下所示:

sorted_dict = sorted(mydict.items(), key=lambda x:x[1])
for id, value in sorted_dict:
    print("{0} {1}".format(id, value))

印刷:

b42b00d6-76c8-4d68-b22e-ff4653bb01c8 1
77d9a028-bd4b-4634-b230-234f88ff010a 2
60eda62f-f05d-4134-9e92-9bb9a1f52daf 2
7e7118cd-7145-41c8-8413-79670bdc81dc 3

按价值排序。

答案 2 :(得分:0)

我的最终解决方案是使用alfasin的答案,并从rbtree切换到pyavl。 Pyavl是一个集合而不是字典,所以它可以有重复。

代码:

import avl

class Item(object):
    def __init__(self, value, id):
        self.value = value
        self.id = id

item1 = Item(1,'b42b00d6-76c8-4d68-b22e-ff4653bb01c8')
item2 = Item(2,'60eda62f-f05d-4134-9e92-9bb9a1f52daf')
item3 = Item(2,'77d9a028-bd4b-4634-b230-234f88ff010a')
item4 = Item(3,'7e7118cd-7145-41c8-8413-79670bdc81dc')

myList = avl.new()
myList.insert(item2)
myList.insert(item1)
myList.insert(item3)
myList.insert(item4)

# Correctly ordered by the first element
for item in myList:
    print "%s %s" % (item.value, item.id)

# But I also need to index by the second element.
# So:

listIndexedBySecondElement = {}
listIndexedBySecondElement[item1.id] = item1
listIndexedBySecondElement[item2.id] = item2
listIndexedBySecondElement[item3.id] = item3
listIndexedBySecondElement[item4.id] = item4

item = listIndexedBySecondElement['7e7118cd-7145-41c8-8413-79670bdc81dc']
print item.value # correctly prints 3

# Now I need to delete an element.

itm = listIndexedBySecondElement['60eda62f-f05d-4134-9e92-9bb9a1f52daf']
del listIndexedBySecondElement['60eda62f-f05d-4134-9e92-9bb9a1f52daf']
myList.remove(itm)