Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sorting a graph by its edge weight. python

Tags:

python

I have a list of tuples of format:

(node1, node2, weight)

What I want to do is sort this tuple so that the the nodes with higher weight are at the top

for example

(A,B,2)
(A,C,5)
(C,A,2)

should give me

(A,C,5)
(A,B,2)
(C,A,2)

The first node is sorted alphabetically. Second node as per the decreasing weight ranks.

like image 222
frazman Avatar asked Jul 20 '12 18:07

frazman


2 Answers

This should work just fine:

lst.sort(key=lambda x:x[2], reverse=True)

Of course, we can avoid the lambda by:

import operator
lst.sort(key=operater.itemgetter(2), reverse=True)

If you want to sort on multiple conditions, you can create interesting functions to return tuples (tuples will sort by first index, then second, then third ...), or you can use the fact that python's sorts are guaranteed to be stable. So, if you want your list to be sorted primarily by weight and then by node name, you just sort first by node name and then by weight. (the backwards order is a little counter intuitive).

If I understand your question (after a re-read and seeing some of the comments here) you're sort can be done as follows:

lst.sort(key=lambda x: (-x[2],x[0])) #relying on tuples

This sorts primarily by weight (high numbers first) and then by node1 alphabetically for objects with the same weight.

Note that this only works if you can negate x[2] to make high numbers appear first in the sort (it wouldn't work for strings for example). A more reliable way to accomplish the same thing (although less efficient?) would be:

lst.sort(key=lambda x: x[0])
lst.sort(key=lambda x: x[2], reversed=True)
like image 196
mgilson Avatar answered Oct 06 '22 07:10

mgilson


Use a "key function". Since you want large weights to sort first, the key function should return the negative of the weight, so that larger weights will sort lower.

A='A'
B='B'
C='C'
lst = [(A, B, 2), (A, C, 5), (C, A, 2)]

def weight_key(tup):
    return tup[0], -tup[2], tup[1]

lst.sort(key=weight_key)
print(lst)  # prints: [('A', 'C', 5), ('A', 'B', 2), ('C', 'A', 2)]

EDIT: I just re-read the question. I'm not exactly sure what this means: "SO, the first node is sorted alphabettically. Second node as per the decreasing weight ranks."

But I think you want the key to be first, sort on the node1 value; then, sort by weight, biggest sorting first; then sort by node2 value. I have edited the key function to return a tuple that would sort this way.

like image 27
steveha Avatar answered Oct 06 '22 07:10

steveha