I would like to sort the list inner of this class. The list contains objects of a cdef class called "Edge". The edge class contains a member variable called "savings". I would like sort the list by this variable.
In order to do that, I create the function sort inside de class, but when I execute the function, I obtain the next error message:
Exception AttributeError: "'fib.Edge' object has no attribute 'savings'" in 'fib.Alist.sort' ignored
Any of you could help me?
cdef class Alist:
def __init__(self):
self.inner = []
cdef list inner
cdef void append(self, Edge a):
self.inner.append(a)
cdef void pop(self, int a):
self.inner.pop(a)
cdef void insert(self,int pos,Edge a):
self.inner.insert(pos,a)
cdef int index(self,Edge a):
if a in self.inner:
return self.inner.index(a)
return -1
cdef Edge get(self, int i):
return <Edge> self.inner[i]
cdef void sort(self):
self.inner.sort(key = lambda c : c.Savings)
#self.inner.sort()
def __len__(self):
return len(self.inner)
def __richcmp__(Edge self, Edge other,int op):
if op == 0:
if self.inner.savings < other.inner.savings:
return True
return FalseI would like to sort the list inner of this class. The list contains objects of a cdef class called "Edge". The edge class contains a member variable called "savings". I would like sort the list by this variable.
In order to do that, I create the function sort inside de class, but when I execute the function, I obtain the next error message:
Exception AttributeError: "'fib.Edge' object has no attribute 'savings'" in 'fib.Alist.sort' ignored
Any of you could help me?
#---------------------------------------------------------------------------- # # sort_example.pyx - 6/2/16 # # A Cython implementation of the minheap algorithm # #---------------------------------------------------------------------------- # Memory allocation for the heap array uses cpython.mem functions from cpython.mem cimport PyMem_Malloc, PyMem_Realloc, PyMem_Free # For managing reference counts from cpython.ref cimport Py_INCREF, Py_DECREF #---------------------------------------------------------------------------- # # The type managed by CyMinHeap ctypedef struct q_item: float t # Event time as a float int priority # Event priority as an int void* evt # The Event object #---------------------------------------------------------------------------- # # Functions for < and > comparison of q_item objects (for priority sorting) # The sort order is first by t then by priority cdef inline int q_item_lt(q_item a, q_item b): if a.t == b.t: return a.priority < b.priority return a.t < b.t #---- cdef inline int q_item_gt(q_item a, q_item b): if a.t == b.t: return a.priority > b.priority return a.t > b.t #---------------------------------------------------------------------------- # # Functions compatible with the Python heapq module def heappush(heap, item): heap.push(item) #---- def heappop(heap): return heap.pop() #---- def heappeek(heap): return heap.peek() #---------------------------------------------------------------------------- # # Replacement for python heapq module specialized for q_item objects. # 7.2x faster than python heapq implementation DEF HEAP_SIZE = 1000 cdef class CyMinHeap: cdef q_item* heap cdef size_t heap_len cdef public int position #---- def __cinit__(self): # allocate uninitialized memory for the heap self.heap = <q_item*> PyMem_Malloc(HEAP_SIZE * sizeof(q_item)) if not self.heap: raise MemoryError() self.heap_len = HEAP_SIZE self.heap[0] = q_item(0.0, 0, NULL) self.position = 0 #---- def __dealloc__(self): PyMem_Free(self.heap) #---- def resize(self, size_t new_number): # Allocates new_number * sizeof(q_item) bytes, # preserving the current content and making a # best-effort to re-use the original data location mem = <q_item*> PyMem_Realloc(self.heap, new_number * sizeof(q_item)) if not mem: raise MemoryError() self.heap = mem self.heap_len = new_number #------------------------------------------------------------------------ # # Python compatible push/pop/peek methods def push(self, obj): if self.position < HEAP_SIZE: # Protect obj from garbage collection Py_INCREF(obj) self.position += 1 self.heap[self.position] = q_item(<float>obj.time, <int>obj.priority, <void *>obj) self.percUp(self.position) else: raise IndexError() #---- def pop(self): cdef object obj if self.position < 1: raise IndexError() obj = <object>self.heap[1].evt # Remove garbage collection protection from obj Py_DECREF(obj) self.heap[1] = self.heap[self.position] self.position -= 1 self.percDown(1) return obj #---- def peek(self): if self.position < 1: raise IndexError() return <object>self.heap[1].evt #---- def __len__(self): return self.position #------------------------------------------------------------------------ # # Methods implementing minheap sorting cdef inline percUp(self,int i): while i / 2 > 0: if q_item_lt(self.heap[i], self.heap[i / 2]): self.heap[i / 2], self.heap[i] = self.heap[i], self.heap[i / 2] i = i / 2 #---- cdef inline percDown(self, int i): cdef int mc while (i * 2) <= self.position: mc = self.minChild(i) if q_item_gt(self.heap[i], self.heap[mc]): self.heap[i], self.heap[mc] = self.heap[mc], self.heap[i] i = mc #---- cdef inline int minChild(self, int i): if i * 2 + 1 > self.position: return i * 2 else: if q_item_lt(self.heap[i*2], self.heap[i*2+1]): return i * 2 else: return i * 2 + 1
#----------------------------------------------------------------------------
#----------------------------------------------------------------------------
#
# test_sort.py - 6/2/16 Test sort_example.pyx
from cy_minheap import CyMinHeap, heappush, heappop
#------------------------------------------------------------------------------
#
# Define the object to be sorted
class Event(object):
def __init__(self, t, p):
self.time = t
self.priority = p
#----
def __str__(self):
return 'Event(%.3f, %d)' % (self.time, self.priority)
#------------------------------------------------------------------------------
def test():
heap = CyMinHeap()
try:
for i in [5,7,0,4,9,2,8,6,1,3]:
heappush(heap, Event(0.0, i))
print 'pushed Event(0.000, %d)' % i
except IndexError:
print 'push on full heap'
print
while 1:
try:
obj = heappop(heap)
print 'popped %s' % obj
except IndexError:
print 'pop from empty heap'
break
test()--------------------------------------------------------------->python test_sort.pypushed Event(0.000, 5)
pushed Event(0.000, 7)
pushed Event(0.000, 0)
pushed Event(0.000, 4)
pushed Event(0.000, 9)
pushed Event(0.000, 2)
pushed Event(0.000, 8)
pushed Event(0.000, 6)
pushed Event(0.000, 1)
pushed Event(0.000, 3)
popped Event(0.000, 0)
popped Event(0.000, 1)
popped Event(0.000, 2)
popped Event(0.000, 3)
popped Event(0.000, 4)
popped Event(0.000, 5)
popped Event(0.000, 6)
popped Event(0.000, 7)
popped Event(0.000, 8)
popped Event(0.000, 9)
pop from empty heap
Vern