Reputation: 97
I am currently working on a program written in Python 2.6.6. It uses a dictionary that looks like:
{ 'somekeystring': someobject("a name", 1, 3),
'anotherkey': someobject("another name", 2, 2),
'keythree': someobject("third name", 3, 1) }
The object has some attributes like:
name
startOrder
stopOrder
What I am trying to accomplish is to get the dictionary sorted. Once by someobject.startOrder, once by someobject.stopOrder.
I have tried
sortedByStartOrder = sorted(mydict.iteritems(), key=lambda x: x[1].startOrder)
but this does not seem to work. The list items are sorted in the same order, no matter if I use startOrder or stopOrder in the example above.
Any hints?
Upvotes: 1
Views: 83
Reputation: 97
Thanks a lot for all your input! I wrote a simple example like Odexios' and it worked perfectly with
sortedByStartOrder = sorted(mydict.iteritems(), key=lambda x: x[1].startOrder)
The clue was:
I'd guess the problem isn't in the sort itself; there might be something wrong in the structures you're trying to sort.
I went through my code and found a code passage where I set both variables to 0.
Upvotes: 1
Reputation: 3923
You can define your own comparing function that is given to the sorted
builtin in the keyword cmp
.
def sort_by_start(obj1, obj2):
# this is just an example using '>' and '<' as comparison operators
# you can compare 1 and 2 using whatever methods you wish; just
# return a negative number if 1 is less than 2, 0 if they are equal
# or a positive number if 1 is greater than 2.
if obj1.startOrder < obj2.startOrder:
return -1
if obj1.startOrder > obj2.startOrder:
return 1
else:
return 0
sorted(mydict.iteritems(), cmp=sort_by_start, key=lambda x: x[1])
def sort_by_stop(obj1, obj2):
# let's make this more specific: imagine `stopOrder` is a string,
# but we need to remove a prefix before we sort them alphabetically
common_prefix = 'id-' # or whatever
comp1 = obj1.stopOrder.lstrip(common_prefix)
comp2 = obj2.stopOrder.lstrip(common_prefix)
if comp1 < comp2:
return -1
if comp1 > comp2:
return 1
else:
return 0
sorted(mydict.iteritems(), cmp=sort_by_stop, key=lambda x: x[1])
Upvotes: 0
Reputation: 1248
This example seems to work for me:
class P:
def __init__(self, x):
self.x = x
d = { 'how': P(3), 'hi': P(2), 'you': P(5), 'are': P(4) }
print list(d.iteritems())
print sorted(d.iteritems(), key=lambda x: x[1].x)
produces
>> [('how', <__main__.P instance at 0x7f92028e52d8>), ('you', <__main__.P instance at 0x7f92028e5368>), ('hi', <__main__.P instance at 0x7f92028e5320>), ('are', <__main__.P instance at 0x7f92028e53b0>)]
>> [('hi', <__main__.P instance at 0x7fc210e6c320>), ('how', <__main__.P instance at 0x7fc210e6c2d8>), ('are', <__main__.P instance at 0x7fc210e6c3b0>), ('you', <__main__.P instance at 0x7fc210e6c368>)]
I'd guess the problem isn't in the sort itself; there might be something wrong in the structures you're trying to sort.
Upvotes: 1