2012-07-20 14 views
5

Tengo una lista de tuplas de formato:ordenando un gráfico por su peso del borde. pitón

(node1, node2, weight) 

Lo que quiero hacer es ordenar esta tupla para que los nodos de mayor peso son en la parte superior

por ejemplo

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

me

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

debería dar al primer nodo está ordenado alfabéticamente Segundo nodo según los rangos de peso decreciente.

+0

¿Se refiere al "borde con mayor peso"? Supongo que la tupla '(nodo1, nodo2, peso)' representa un borde. –

Respuesta

9

Esto debería funcionar bien:

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

Por supuesto, podemos evitar la lambda por:

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

Si desea ordenar en múltiples condiciones, puede crear funciones interesantes para volver tuplas (las tuplas se ordenarán por el primer índice, luego el segundo, luego el tercero ...), o puede usar el hecho de que los géneros de python tienen la garantía de ser estables. Por lo tanto, si desea que su lista se ordene principalmente por peso y luego por nombre de nodo, solo debe ordenar primero por nombre de nodo y luego por peso. (el orden inverso es un pequeño contador intuitivo).

Si entiendo su pregunta (después de una re-leer y ver algunos de los comentarios aquí) que está especie se puede realizar como sigue:

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

Esto ordena principalmente en peso (los números altos primero) y luego por node1 alfabéticamente para objetos con el mismo peso.

Tenga en cuenta que esto solo funciona si puede negar x[2] para hacer que los números altos aparezcan primero en el orden (no funcionaría para cadenas, por ejemplo). Una forma más confiable de lograr lo mismo (aunque menos eficiente?) Sería:

lst.sort(key=lambda x: x[0]) 
lst.sort(key=lambda x: x[2], reversed=True) 
+0

No necesita mi aprobación ... su respuesta ahora es completa y exhaustiva. Eliminaré mi comentario anterior. – steveha

+0

@steveha - Sé que no. Pero quiero que sea una buena respuesta. Si puedo mejorarlo, lo haré. Gracias por tus comentarios. Yo creo que es mejor ahora. – mgilson

+0

Es una respuesta muy completa ahora.Me gusta especialmente el ejemplo al final de usar el género "estable" con dos pasos para lograr lo mismo, donde no podemos simplemente construir una tupla con un valor negado. – steveha

5

Utilice una "función de tecla". Dado que usted desea que los pesos grandes se clasifiquen primero, la función clave debe devolver el valor negativo del peso, de modo que los pesos más grandes se clasifiquen más bajos.

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: Acabo de volver a leer la pregunta. No estoy exactamente seguro de lo que esto significa: "ASÍ, el primer nodo se ordena alfabéticamente. El segundo nodo se clasifica según el peso decreciente".

Pero creo que quieres que la llave sea la primera, ordena el valor node1; luego, clasifique por peso, mayor clasificación primero; luego ordenar por valor de node2. He editado la función clave para devolver una tupla que se ordenaría de esta manera.

Cuestiones relacionadas