我想使用bisect(如此处所示,在第二个答案中:Does python have a sorted list?), 但我没有使用数字列表,而是有一个对象列表。具体而言,此类中的对象:https://networkx.github.io/documentation/latest/_modules/networkx/classes/graph.html
我希望列表能够按照节点数量对图表进行排序。 如果我将这些图形推入列表中,看起来它是以任意方式插入的(如果我多次运行它,它会在运行之间发生变化)。
有"排序"每个类可以定义的函数,在应用排序时,它将被使用(就像在其他语言中重写操作符一样)?
import bisect
import networkx as nx
L=[]
G1 = nx.Graph()
G2 = nx.Graph()
G1.add_edges_from([(1,2),(1,3),(2,3),(3,4),(4,5),(4,6),(5,6),(4,7),(7,8),(7,9),(8,9)])
print 'G1', G1.number_of_nodes()
G2.add_edges_from([(1,2),(1,3)])
print 'G2', G2.number_of_nodes()
bisect.insort(L,G1)
bisect.insort(L,G2)
print 'L0 ', L[0].number_of_nodes()
print 'L1' ,L[1].number_of_nodes()
如果有另一种方法,那就太棒了。
由于
答案 0 :(得分:1)
列表的某些任意顺序是由于对象按id排序(它是从CPython中对象的RAM地址派生的),除非它们提供了一些定义排序的其他方法。
解决问题的简单方法是简单地使用内置的list.sort
方法(或sorted
函数),将key=len
作为关键函数参数传递。
但是,如果您想使用bisect
维护已排序的列表,也可以这样做,但您的类需要定义Rich Comparison methods。
你可以将这些方法添加到图表类中,但将新类定义为包装器可能更容易(也更清晰)。
这是一个包含内置list
类型的简单示例。它定义了一个私有方法_cmp
来执行基于长度的比较,而Rich Comparison“magic”方法调用_cmp
。为了提高效率,应该直接定义Rich Comparison方法 ,以避免调用另一个方法,但使用_cmp
更容易阅读(和写:) :)。
import bisect
class MyList(object):
def __init__(self, data):
self.data = data
def __repr__(self):
return 'MyList({0!r})'.format(self.data)
def _cmp(self, other):
return len(self.data) - len(other.data)
#Rich comparison methods
def __lt__(self, other):
return self._cmp(other) < 0
def __le__(self, other):
return self._cmp(other) <= 0
def __eq__(self, other):
return self._cmp(other) == 0
def __ne__(self, other):
return self._cmp(other) != 0
def __ge__(self, other):
return self._cmp(other) >= 0
def __gt__(self, other):
return self._cmp(other) > 0
data = (
[50, 60],
[10, 20, 30],
[1, 2, 3, 4, 5],
[5, 6],
[7, 8, 9, 10],
)
blist = []
for seq in data:
a = MyList(seq)
bisect.insort(blist, a)
print(a)
print(blist)
print()
<强>输出强>
MyList([50, 60])
[MyList([50, 60])]
MyList([10, 20, 30])
[MyList([50, 60]), MyList([10, 20, 30])]
MyList([1, 2, 3, 4, 5])
[MyList([50, 60]), MyList([10, 20, 30]), MyList([1, 2, 3, 4, 5])]
MyList([5, 6])
[MyList([50, 60]), MyList([5, 6]), MyList([10, 20, 30]), MyList([1, 2, 3, 4, 5])]
MyList([7, 8, 9, 10])
[MyList([50, 60]), MyList([5, 6]), MyList([10, 20, 30]), MyList([7, 8, 9, 10]), MyList([1, 2, 3, 4, 5])]
您可能希望看一下heapq
:您可能会发现它比bisect
更适合您的目的。 heapq
(当然)将使用Rich Comparison方法(如果已定义)。