Come posso riordinare un elenco? [chiuso]


108

Se ho una lista [a,b,c,d,e]come posso riordinare gli articoli in modo arbitrario come [d,c,a,b,e]?

Modifica: non voglio mescolarli. Voglio riordinarli in modo predefinito. (ad esempio, so che il terzo elemento nel vecchio elenco dovrebbe diventare il primo elemento nel nuovo elenco)


Probabilmente il duplicato della stackoverflow.com/questions/976882/...
kgiannakakis

4
Senza specificare come si desidera ordinare gli articoli è difficile rispondere. Li vuoi ordinare? Mescolali? Rimuovere alcuni di loro?
Mizipzor

@tvanfosson: In questo caso, arbitrario potrebbe anche significare: prendere una funzione di ordinamento arbitraria (ma ben definita).
Felix Kling

1
@mizipzor voglio riordinarli in modo predefinito. (Ha modificato la domanda per chiarire questo)
Niyaz

@SilentGhost Avrà un nuovo indice. Può essere 4. Il punto è che conosco il nuovo ordine degli articoli.
Niyaz

Risposte:


226

Puoi farlo in questo modo

mylist = ['a', 'b', 'c', 'd', 'e']
myorder = [3, 2, 0, 1, 4]
mylist = [mylist[i] for i in myorder]
print(mylist)         # prints: ['d', 'c', 'a', 'b', 'e']

1
Questo crea una nuova variabile. Come riordinare un elenco sul posto? Grazie
Confuso

@Confounded Cambia semplicemente l'ultima riga in:mylist[:] = [mylist[i] for i in myorder]
Adam


11
>>> import random
>>> x = [1,2,3,4,5]
>>> random.shuffle(x)
>>> x
[5, 2, 4, 3, 1]

@ wenlibin02, l'ho appena eseguito con la versione 2.7.5 e funziona ancora bene. Ricevi una sorta di errore?
Mark

nessun errore, digito solo: 1) import random; x = [1, 2, 3]; random.shuffle (x); # restituisce Nessuno; e 2) ho provato np.random.shuffle. i risultati sono gli stessi.
Libin Wen

Oh scusa! Non mi ero accorto di modificare direttamente il valore di x. Ha restituito Nessuno. E funziona. Grazie.
Libin Wen


3
>>> a=["a","b","c","d","e"]
>>> a[0],a[3] = a[3],a[0]
>>> a
['d', 'b', 'c', 'a', 'e']

2

Puoi fornire la tua funzione di ordinamento a list.sort():

Il metodo sort () accetta argomenti opzionali per controllare i confronti.

  • cmp specifica una funzione di confronto personalizzata di due argomenti (lista elementi) che restituisce il negativo, zero o numero positivo a seconda che il primo argomento è considerato minore, uguale o maggiore del secondo argomento: cmp=lambda x,y: cmp(x.lower(), y.lower()). Il valore predefinito è None.

  • chiave specifica una funzione di un argomento che viene usato per estrarre una chiave di confronto da ogni elemento della lista: key=str.lower. Il valore predefinito è None.

  • reverse è un valore booleano. Se impostato su True, gli elementi dell'elenco vengono ordinati come se ogni confronto fosse invertito.

In generale, i processi di conversione chiave e inversa sono molto più veloci rispetto alla specifica di una funzione cmp equivalente. Questo perché cmp viene chiamato più volte per ogni elemento della lista mentre key e reverse toccano ogni elemento solo una volta.


2
e come lo implementeresti esattamente?
SilentGhost

@ SilentGhost: questa è da intendersi come una risposta generale. Nel caso dei PO la tua risposta è più appropriata. Tuttavia penso sia importante sapere che esiste una soluzione generica.
Felix Kling

2

Se usi numpy c'è un modo semplice per farlo:

items = np.array(["a","b","c","d"])
indices = np.arange(items.shape[0])
np.random.shuffle(indices)
print(indices)
print(items[indices])

Questo codice restituisce:

[1 3 2 0]
['b' 'd' 'c' 'a']

1
OP sta cercando un riordino specifico, non un mescolamento generico.
Teepeemm

2

Se non ti interessa così tanto l'efficienza, puoi fare affidamento sull'indicizzazione dell'array di numpy per renderlo elegante:

a = ['123', 'abc', 456]
order = [2, 0, 1]
a2 = list( np.array(a, dtype=object)[order] )

1

Da quello che ho capito della tua domanda, sembra che tu voglia applicare una permutazione che specifichi su un file list. Questo viene fatto specificando un altro list(chiamiamolo p) che contiene gli indici degli elementi dell'originale listche dovrebbero apparire nel permutato list. Puoi quindi pcrearne uno nuovo listsemplicemente sostituendo l'elemento in ciascuna posizione con quello il cui indice si trova in quella posizione in p.

def apply_permutation(lst, p):
    return [lst[x] for x in p]

arr=list("abcde")
new_order=[3,2,0,1,4]

print apply_permutation(arr,new_order)

Questo stampa ['d', 'c', 'a', 'b', 'e'].

Questo in realtà crea un nuovo list, ma può essere banalmente modificato per permutare l'originale "sul posto".


1

Un'altra cosa che può essere considerata è l'altra interpretazione indicata da darkless

Codice in Python 2.7

Principalmente:

  1. Riordina in base al valore - Già risolto da AJ sopra
  2. Riordina per indice

    mylist = ['a', 'b', 'c', 'd', 'e']
    myorder = [3, 2, 0, 1, 4]
    
    mylist = sorted(zip(mylist, myorder), key=lambda x: x[1])
    print [item[0] for item in mylist]

Questo stamperà ['c', 'd', 'b', 'a', 'e']



-1

Questo è quello che ho usato quando mi sono imbattuto in questo problema.

def order(list_item, i): # reorder at index i
    order_at = list_item.index(i)
    ordered_list = list_item[order_at:] + list_item[:order_at]
    return ordered_list

EX: per le lettere minuscole

order(string.ascii_lowercase, 'h'):
>>> 'hijklmnopqrstuvwxyzabcdefg'

Sposta semplicemente l'elenco a un indice specificato

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.