121 votes

Comment fonctionnent les fonctions operator.itemgetter() et sort() ?

J'ai le code suivant :

# initialize
a = []

# create the table (name, age, job)
a.append(["Nick", 30, "Doctor"])
a.append(["John",  8, "Student"])
a.append(["Paul", 22, "Car Dealer"])
a.append(["Mark", 66, "Retired"])    

# sort the table by age
import operator
a.sort(key=operator.itemgetter(1))    

# print the table
print(a)

Il crée un tableau 4x3 et le trie par âge. Ma question est la suivante : qu'est-ce que key=operator.itemgetter(1) fait ? Est-ce que le operator.itemgetter retourne la valeur de l'élément ? Pourquoi ne puis-je pas simplement taper quelque chose comme key=a[x][1] là ? Ou puis-je le faire ? Comment pourrait-on avec l'opérateur imprimer une certaine valeur de la forme comme 3x2 qui est 22 ?

  1. Comment Python fait-il exactement pour trier le tableau ? Puis-je le trier à l'envers ?

  2. Comment puis-je le trier sur la base de deux colonnes, par exemple l'âge, puis le nom si l'âge est le même ?

  3. Comment pourrais-je le faire sans operator ?

168voto

J0HN Points 10486

On dirait que tu es un peu confus à propos de tout ça.

operator est un module intégré qui fournit un ensemble d'opérateurs pratiques. En deux mots operator.itemgetter(n) construit un appelable qui prend un objet itérable (par exemple une liste, un tuple, un ensemble) en entrée, et en extrait le n-ième élément.

Donc, vous ne pouvez pas utiliser key=a[x][1] là, car python n'a aucune idée de ce que x est. Au lieu de cela, vous pouvez utiliser un lambda fonction ( elem est juste un nom de variable, pas de magie là-dedans) :

a.sort(key=lambda elem: elem[1])

Ou juste une fonction ordinaire :

def get_second_elem(iterable):
    return iterable[1]

a.sort(key=get_second_elem)

Voici donc une note importante : en python, les fonctions sont des citoyens de premier ordre Vous pouvez donc les passer en paramètre à d'autres fonctions.

Autres questions :

  1. Oui, vous pouvez inverser le tri, il suffit d'ajouter reverse=True : a.sort(key=..., reverse=True)
  2. Pour trier par plus d'une colonne, vous pouvez utiliser itemgetter avec plusieurs indices : operator.itemgetter(1,2) ou avec lambda : lambda elem: (elem[1], elem[2]) . De cette façon, des itérables sont construits à la volée pour chaque élément de la liste, qui sont ensuite comparés les uns aux autres dans l'ordre lexicographique ( ?) (les premiers éléments sont comparés, s'ils sont égaux - les seconds éléments sont comparés, etc).
  3. Vous pouvez récupérer la valeur à [3,2] en utilisant a[2,1] (les indices sont basés sur le zéro). Utiliser un opérateur... C'est possible, mais pas aussi propre qu'une simple indexation.

Reportez-vous à la documentation pour plus de détails :

  1. operator.itemgetter a expliqué
  2. Trier une liste par une clé personnalisée en Python

53voto

Lutz Prechelt Points 470

Réponse pour les débutants en Python

En termes plus simples :

  1. En key= paramètre de sort nécessite une clé fonction (à appliquer aux objets à trier) plutôt qu'une seule clé valeur y
  2. c'est juste ce que operator.itemgetter(1) vous donnera : A fonction qui saisit le premier élément d'un objet de type liste.

(Plus précisément, ce sont callables et non les fonctions, mais c'est une différence qui peut souvent être ignorée).

21voto

Paulo Almeida Points 2355

Vous posez beaucoup de questions auxquelles vous pourriez répondre vous-même en lire la documentation Je vais donc vous donner un conseil général : lisez-le et expérimentez dans le shell python. Vous verrez que itemgetter renvoie un appelant :

>>> func = operator.itemgetter(1)
>>> func(a)
['Paul', 22, 'Car Dealer']
>>> func(a[0])
8

Pour le faire d'une manière différente, vous pouvez utiliser lambda :

a.sort(key=lambda x: x[1])

Et inversez-la :

a.sort(key=operator.itemgetter(1), reverse=True)

Trier par plus d'une colonne :

a.sort(key=operator.itemgetter(1,2))

Voir le trier comment faire .

1voto

user2329366 Points 69
#sorting first by age then profession,you can change it in function "fun".
a = []

def fun(v):
    return (v[1],v[2])

# create the table (name, age, job)
a.append(["Nick", 30, "Doctor"])
a.append(["John",  8, "Student"])
a.append(["Paul",  8,"Car Dealer"])
a.append(["Mark", 66, "Retired"])

a.sort(key=fun)

print a

0voto

shubham sinha Points 11
a = []
a.append(["Nick", 30, "Doctor"])
a.append(["John",  8, "Student"])
a.append(["Paul",  8,"Car Dealer"])
a.append(["Mark", 66, "Retired"])
print a

[['Nick', 30, 'Doctor'], ['John', 8, 'Student'], ['Paul', 8, 'Car Dealer'], ['Mark', 66, 'Retired']]

def _cmp(a,b):     

    if a[1]<b[1]:
        return -1
    elif a[1]>b[1]:
        return 1
    else:
        return 0

sorted(a,cmp=_cmp)

[['John', 8, 'Student'], ['Paul', 8, 'Car Dealer'], ['Nick', 30, 'Doctor'], ['Mark', 66, 'Retired']]

def _key(list_ele):

    return list_ele[1]

sorted(a,key=_key)

[['John', 8, 'Student'], ['Paul', 8, 'Car Dealer'], ['Nick', 30, 'Doctor'], ['Mark', 66, 'Retired']]
>>>

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X