2012-07-20 8 views
5

Ho una lista di tuple di formato:ordinamento di un grafico in base al peso del bordo. python

(node1, node2, weight) 

Quello che voglio fare è sorta questa tupla in modo che i nodi con peso più elevato sono in cima

ad esempio

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

me

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

dovrebbe dare il primo nodo è ordinato alfabeticamente. Secondo nodo come per i gradi di peso decrescente.

+0

Intendi il "bordo con peso superiore"? Suppongo che la tupla '(nodo1, nodo2, peso)' rappresenti un bordo. –

risposta

9

Questo dovrebbe funzionare bene:

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

Naturalmente, siamo in grado di evitare il lambda da:

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

Se si desidera ordinare su più condizioni, è possibile creare funzioni interessanti per tornare tuple (le tuple si ordinano per primo indice, poi secondo, poi terzo ...), oppure puoi usare il fatto che i tipi di python sono garantiti come stabili. Quindi, se si desidera che l'elenco sia ordinato principalmente in base al peso e quindi in base al nome del nodo, basta ordinare prima il nome del nodo e poi il peso. (l'ordine inverso è un po 'controintuitivo).

Se ho capito la tua domanda (dopo una ri-leggere e vedere alcuni dei commenti qui) si sta sorta può essere fatto come segue:

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

Questo ordina in primo luogo, in peso (un numero elevato prima) e quindi da node1 alfabeticamente per oggetti con lo stesso peso.

Si noti che questo funziona solo se è possibile negare x[2] affinché i numeri alti vengano visualizzati per primi nell'ordinamento (ad esempio, non funzionerebbe con le stringhe). Un modo più affidabile per realizzare la stessa cosa (anche se meno efficiente?) Sarebbe:

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

Non hai bisogno della mia approvazione ... la tua risposta è ora completa e completa. Cancellerò il mio commento precedente. – steveha

+0

@steveha - Lo so che non lo so. Ma voglio che sia una buona risposta. Se posso migliorarlo, lo farò. Grazie per il vostro feedback Penso che sia meglio ora. – mgilson

+0

È una risposta molto completa ora.In particolare mi piace l'esempio alla fine di usare lo "stabile" ordinamento con due passaggi per realizzare la stessa cosa, dove non possiamo semplicemente costruire una tupla con un valore negato. – steveha

5

Utilizzare una "funzione chiave". Dal momento che si desidera innanzitutto ordinare i pesi di grandi dimensioni, la funzione chiave dovrebbe restituire il peso negativo, in modo che i pesi più grandi si ordinino più in basso.

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: Ho appena riletto la domanda. Non sono esattamente sicuro di cosa significhi: "SO, il primo nodo è ordinato alfabeticamente, secondo nodo come per i gradi di peso decrescenti."

Ma penso che si desidera che la chiave sia la prima, ordinare sul valore node1; quindi, ordina per peso, prima il più grande ordinamento; quindi ordinare per valore node2. Ho modificato la funzione chiave per restituire una tupla che sarebbe ordinata in questo modo.

Problemi correlati