2017-10-19 6 views
0

Je tente de trier une liste de listes par chaque index de la liste interne. (Toutes les listes internes ont la même longueur.) Le but est de trier d'abord les lignes par la dernière colonne (le dernier index des listes internes), puis par la colonne/index précédent et ainsi de suite.Python- Trier une liste de listes par plusieurs index, où les listes internes peuvent inclure "Aucun"

Entrée:

[ 
    ['2016', 'E', None, '68', '94'], 
    ['2016', 'A', None, '91', '25'], 
    ['2016', 'C', None, '74', '25'], 
    ['2017', 'C', None, '55', '20'], 
    ['2015', 'D', None, '20', '14'], 
    ['2016', 'B', None, '66', '66'], 
    ['2017', 'E', None, '29', '41'], 
    ['2017', 'F', None, '61', '22'], 
    ['2015', 'A', None, '17', '96'] 
] 

Sortie:

[ 
    ['2015', 'A', None, '17', '96'], 
    ['2015', 'D', None, '20', '14'], 
    ['2016', 'A', None, '91', '25'], 
    ['2016', 'B', None, '66', '66'], 
    ['2016', 'C', None, '74', '25'], 
    ['2016', 'E', None, '68', '94'], 
    ['2017', 'C', None, '55', '20'], 
    ['2017', 'E', None, '29', '41'], 
    ['2017', 'F', None, '61', '22'] 
] 

je la pièce suivante de code que je suis en train d'utiliser pour cela:

def sort_table(column_count, rows) 
    for i in range(len(column_count) - 1, -1, -1): 
    rows = sorted(rows, key=operator.itemgetter(i)) 
    return rows 

Cependant, il semble être jeté par le fait qu'il existe ou peut être None valeurs dans la liste. Je continue d'obtenir l'erreur TypeError: '<' not supported between instances of 'NoneType' and 'str'. Y a-t-il une bonne façon de gérer cela?

+1

https://stackoverflow.com/questions/12971631/sorting-list-by-an-attribute-that-can-be-none – Rockybilly

+1

Il suffit d'utiliser [ 'trié'] (https://docs.python.org/dev/library/functions.html#sorted) –

+0

@PatrickHaugh - J'utilise trié. Que devrais-je faire différemment? – ebbishop

Répondre

3

Utilisez triée sur votre liste multidimensionnelle

l = [ 
    ['2016', 'E', None, '68', '94'], 
    ['2016', 'A', None, '91', '25'], 
    ['2016', 'C', None, '74', '25'], 
    ['2017', 'C', None, '55', '20'], 
    ['2015', 'D', None, '20', '14'], 
    ['2016', 'B', None, '66', '66'], 
    ['2017', 'E', None, '29', '41'], 
    ['2017', 'F', None, '61', '22'], 
    ['2015', 'A', None, '17', '96'] 
] 
print(sorted(l)) 

impressions

[['2015', 'A', None, '17', '96'], ['2015', 'D', None, '20', '14'], ['2016', 'A', None, '91', '25'], ['2016', 'B', None, '66', '66'], ['2016', 'C', None, '74', '25'], ['2016', 'E', None, '68', '94'], ['2017', 'C', None, '55', '20'], ['2017', 'E', None, '29', '41'], ['2017', 'F', None, '61', '22']] 

Quelle est la même que votre puissance nécessaire

+1

Ou si vous voulez le tri fait par le dernier index (comme dans la description mais pas l'exemple de sortie) utilisez 'trié (l, clé = inversé)' – Holloway

+0

@Holloway Ce n'est pas que je veux trier dans l'ordre inverse de celui que j'ai montré dans les résultats, c'est juste que je pensais que je devrais trier chaque index séparément, donc je travaillais mon chemin à travers les indices pour obtenir l'effet désiré. – ebbishop

1

En dehors de la key, la fonction sorted vous permet également de personnaliser la fonction de comparaison, en transmettant un argument cmp. Passez juste une fonction de deux arguments qui retourne négatif si le premier argument est plus petit, positif s'il est plus grand, zéro s'ils sont égaux. En fonction de ce que vous voulez, vous pouvez faire quelque chose comme

import numpy as np 

def mycomparator(a, b): 
    if a is None: 
     return -1 
    return np.sign(a - b) 

sorted(..., cmp=mycomparator, key=...) 
+0

Merci pour l'astuce sur l'argument 'cmp' – ebbishop

+1

@ebbishop, gardez à l'esprit que le mot-clé' cmp' a été supprimé dans Python 3. – Holloway