Je ne comprends pas très bien la syntaxe derrière l' sorted()
argument:
key=lambda variable: variable[0]
N'est-ce pas lambda
arbitraire? Pourquoi est-il variable
indiqué deux fois dans ce qui ressemble à un dict
?
Je ne comprends pas très bien la syntaxe derrière l' sorted()
argument:
key=lambda variable: variable[0]
N'est-ce pas lambda
arbitraire? Pourquoi est-il variable
indiqué deux fois dans ce qui ressemble à un dict
?
Réponses:
key
est une fonction qui sera appelée pour transformer les éléments de la collection avant leur comparaison. Le paramètre passé à key
doit être quelque chose qui peut être appelé.
L'utilisation de lambda
crée une fonction anonyme (qui peut être appelée). Dans le cas de sorted
l'appelable ne prend qu'un seul paramètre. Python lambda
est assez simple. Il ne peut faire et renvoyer qu'une seule chose en réalité.
La syntaxe de lambda
est le mot lambda
suivi de la liste des noms de paramètres puis d'un seul bloc de code. La liste des paramètres et le bloc de code sont délimités par deux points. Ceci est similaire à d' autres constructions en python aussi bien comme while
, for
, if
et ainsi de suite. Ce sont toutes des instructions qui ont généralement un bloc de code. Lambda n'est qu'une autre instance d'une instruction avec un bloc de code.
On peut comparer l'utilisation de lambda avec celle de def pour créer une fonction.
adder_lambda = lambda parameter1,parameter2: parameter1+parameter2
def adder_regular(parameter1, parameter2): return parameter1+parameter2
lambda nous donne simplement un moyen de faire cela sans attribuer de nom. Ce qui le rend idéal pour une utilisation en tant que paramètre d'une fonction.
variable
est utilisé deux fois ici car sur la gauche du signe deux-points, c'est le nom d'un paramètre et sur le côté droit, il est utilisé dans le bloc de code pour calculer quelque chose.
Je pense que toutes les réponses ici couvrent assez bien ce que fait la fonction lambda dans le contexte de sorted (), mais j'ai toujours l'impression qu'une description qui conduit à une compréhension intuitive fait défaut, alors voici mes deux cents.
Par souci d'exhaustivité, je vais énoncer l'évidence dès le départ: sorted () renvoie une liste d'éléments triés et si nous voulons trier d'une manière particulière ou si nous voulons trier une liste complexe d'éléments (par exemple des listes imbriquées ou une liste de tuples), nous pouvons invoquer l'argument clé.
Pour moi, la compréhension intuitive de l'argument clé, pourquoi il doit être appelable et l'utilisation de lambda comme fonction appelable (anonyme) pour accomplir cela se décompose en deux parties.
La syntaxe Lambda est la suivante:
lambda input_variable (s) : savoureux une doublure
par exemple
In [1]: f00 = lambda x: x/2
In [2]: f00(10)
Out[2]: 5.0
In [3]: (lambda x: x/2)(10)
Out[3]: 5.0
In [4]: (lambda x, y: x / y)(10, 2)
Out[4]: 5.0
In [5]: (lambda: 'amazing lambda')() # func with no args!
Out[5]: 'amazing lambda'
key
argument est qu'il devrait prendre un ensemble d'instructions qui pointeront essentiellement la fonction 'sorted ()' sur les éléments de liste qui devraient être utilisés pour trier. Quand il dit key=
, ce que cela signifie vraiment est: En parcourant la liste un élément à la fois (c'est-à-dire pour e dans la liste), je vais passer l'élément actuel à la fonction que je fournis dans l'argument clé et l'utiliser pour créer une liste transformée qui m'informera de l'ordre de la liste triée finale.Vérifiez-le:
mylist = [3,6,3,2,4,8,23]
sorted(mylist, key=WhatToSortBy)
Exemple de base:
sorted(mylist)
[2, 3, 3, 4, 6, 8, 23] # tous les nombres sont dans l'ordre du petit au grand.
Exemple 1:
mylist = [3,6,3,2,4,8,23]
sorted(mylist, key=lambda x: x%2==0)
[3, 3, 23, 6, 2, 4, 8] # Ce résultat trié a-t-il un sens intuitif pour vous?
Notez que ma fonction lambda a dit à trié de vérifier si (e) était pair ou impair avant le tri.
MAIS ATTENDEZ! Vous vous demandez peut-être (ou devriez peut-être) deux choses - d'abord, pourquoi mes chances viennent-elles avant mes evens (puisque ma valeur clé semble indiquer à ma fonction triée de prioriser les evens en utilisant l'opérateur mod in x%2==0
). Deuxièmement, pourquoi mes evens sont-ils hors service? 2 vient avant 6, non? En analysant ce résultat, nous apprendrons quelque chose de plus profond sur le fonctionnement de l'argument 'key' sorted (), en particulier en conjonction avec la fonction lambda anonyme.
Tout d'abord, vous remarquerez que même si les probabilités précèdent les vents, les vents eux-mêmes ne sont pas triés. Pourquoi est-ce?? Permet de lire les documents :
Fonctions clés À partir de Python 2.4, list.sort () et sorted () ont ajouté un paramètre clé pour spécifier une fonction à appeler sur chaque élément de la liste avant de faire des comparaisons.
Nous devons faire un peu de lecture entre les lignes ici, mais ce que cela nous dit, c'est que la fonction de tri n'est appelée qu'une seule fois, et si nous spécifions l'argument clé, nous trions par la valeur vers laquelle la fonction clé nous indique.
Alors, qu'est-ce que l'exemple utilisant un retour modulo? Une valeur booléenne: True == 1
, False == 0
. Alors, comment trié traite-t-il cette clé? Il transforme essentiellement la liste d'origine en une séquence de 1 et de 0.
[3,6,3,2,4,8,23] devient [0,1,0,1,1,1,0]
Maintenant, nous arrivons quelque part. Qu'obtenez-vous lorsque vous triez la liste transformée?
[0,0,0,1,1,1,1]
D'accord, alors maintenant nous savons pourquoi les chances passent avant les égales. Mais la question suivante est: pourquoi le 6 vient-il toujours avant le 2 dans ma liste finale? Eh bien, c'est facile - c'est parce que le tri ne se produit qu'une seule fois! c'est-à-dire que ces 1 représentent toujours les valeurs de liste d'origine, qui sont dans leurs positions d'origine les unes par rapport aux autres. Étant donné que le tri ne se produit qu'une seule fois et que nous n'appelons aucun type de fonction de tri pour ordonner les valeurs paires d'origine de bas en haut, ces valeurs restent dans leur ordre d'origine les unes par rapport aux autres.
La dernière question est alors la suivante: comment est-ce que je pense conceptuellement à la façon dont l'ordre de mes valeurs booléennes est transformé en valeurs d'origine lorsque j'imprime la liste triée finale?
Sorted () est une méthode intégrée qui (fait amusant) utilise un algorithme de tri hybride appelé Timsortqui combine les aspects du tri par fusion et du tri par insertion. Il me semble clair que lorsque vous l'appelez, il y a un mécanisme qui garde ces valeurs en mémoire et les regroupe avec leur identité booléenne (masque) déterminée par (...!) La fonction lambda. L'ordre est déterminé par leur identité booléenne calculée à partir de la fonction lambda, mais gardez à l'esprit que ces sous-listes (de un et de zéros) ne sont pas elles-mêmes triées par leurs valeurs d'origine. Par conséquent, la liste finale, bien qu'organisée par Odds and Evens, n'est pas triée par sous-liste (les evens dans ce cas sont dans le désordre). Le fait que les cotes soient ordonnées est parce qu'elles étaient déjà dans l'ordre par coïncidence dans la liste d'origine. Ce qu'il faut retenir de tout cela, c'est que lorsque lambda effectue cette transformation, l'ordre d'origine des sous-listes est conservé.
Alors, comment tout cela se rapporte-t-il à la question d'origine et, plus important encore, à notre intuition sur la façon dont nous devrions implémenter sorted () avec son argument clé et lambda?
Cette fonction lambda peut être considérée comme un pointeur qui pointe vers les valeurs sur lesquelles nous devons trier, qu'il s'agisse d'un pointeur mappant une valeur à son booléen transformé par la fonction lambda, ou s'il s'agit d'un élément particulier dans une liste imbriquée, un tuple, dict, etc., à nouveau déterminé par la fonction lambda.
Essayons de prédire ce qui se passe lorsque j'exécute le code suivant.
mylist = [(3, 5, 8), (6, 2, 8), ( 2, 9, 4), (6, 8, 5)]
sorted(mylist, key=lambda x: x[1])
Mon sorted
appel dit évidemment: "Veuillez trier cette liste". L'argument clé rend cela un peu plus précis en disant, pour chaque élément (x) dans mylist, renvoyer l'index 1 de cet élément, puis trier tous les éléments de la liste d'origine 'mylist' par l'ordre trié de la liste calculée par la fonction lambda. Puisque nous avons une liste de tuples, nous pouvons renvoyer un élément indexé à partir de ce tuple. On obtient donc:
[(6, 2, 8), (3, 5, 8), (6, 8, 5), (2, 9, 4)]
Exécutez ce code et vous constaterez que c'est l'ordre. Essayez d'indexer une liste d'entiers et vous constaterez que le code se brise.
Ce fut une longue explication, mais j'espère que cela vous aidera à «trier» votre intuition sur l'utilisation des fonctions lambda comme argument clé dans sorted () et au-delà.
key
fonction n'était pas claire . Si vous essayez de comprendre la sorted
fonction, la lambda
syntaxe ne fait que vous empêcher de comprendre.
lambda
est un mot-clé Python utilisé pour générer des fonctions anonymes .
>>> (lambda x: x+2)(3)
5
3
parce qu'ils sont passés à une fonction. Les parens sont autour du lambda afin que l'expression ne soit pas analysée comme lambda x: x+2(3)
, ce qui n'est pas valide car 2
n'est pas une fonction.
Un autre exemple d'utilisation de la fonction sorted () avec key = lambda. Considérons que vous avez une liste de tuples. Dans chaque tuple, vous avez une marque, un modèle et un poids de la voiture et vous souhaitez trier cette liste de tuples par marque, modèle ou poids. Vous pouvez le faire avec lambda.
cars = [('citroen', 'xsara', 1100), ('lincoln', 'navigator', 2000), ('bmw', 'x5', 1700)]
print(sorted(cars, key=lambda car: car[0]))
print(sorted(cars, key=lambda car: car[1]))
print(sorted(cars, key=lambda car: car[2]))
Résultats:
[('bmw', 'x5', '1700'), ('citroen', 'xsara', 1100), ('lincoln', 'navigator', 2000)]
[('lincoln', 'navigator', 2000), ('bmw', 'x5', '1700'), ('citroen', 'xsara', 1100)]
[('citroen', 'xsara', 1100), ('bmw', 'x5', 1700), ('lincoln', 'navigator', 2000)]
Étant donné que l'utilisation de lambda a été demandée dans le contexte de sorted()
, jetez un œil à ceci également https://wiki.python.org/moin/HowTo/Sorting/#Key_Functions
Juste pour reformuler, la clé (facultative. Une fonction à exécuter pour décider de l'ordre. La valeur par défaut est Aucune) dans les fonctions triées attend une fonction et vous utilisez lambda.
Pour définir lambda, vous spécifiez la propriété d'objet que vous souhaitez trier et la fonction triée intégrée de python s'en chargera automatiquement.
Si vous souhaitez trier par plusieurs propriétés, attribuez key = lambda x: (propriété1, propriété2).
Pour spécifier l'ordre par ordre, passez reverse = true comme troisième argument (facultatif. Une valeur booléenne. False triera par ordre croissant, True triera par ordre décroissant. La valeur par défaut est False) de la fonction triée.
Réponse simple et rapide avec un exemple correspondant à la question posée Suivez cet exemple:
user = [{"name": "Dough", "age": 55},
{"name": "Ben", "age": 44},
{"name": "Citrus", "age": 33},
{"name": "Abdullah", "age":22},
]
print(sorted(user, key=lambda el: el["name"]))
print(sorted(user, key= lambda y: y["age"]))
Regardez les noms dans la liste, ils commencent par D, B, C et A. Et si vous remarquez les âges, ils sont 55, 44, 33 et 22. Le premier code d'impression
print(sorted(user, key=lambda el: el["name"]))
Résultats à:
[{'name': 'Abdullah', 'age': 22},
{'name': 'Ben', 'age': 44},
{'name': 'Citrus', 'age': 33},
{'name': 'Dough', 'age': 55}]
trie le nom, car par key = lambda el: el ["name"] nous trions les noms et les noms retournés par ordre alphabétique.
Le deuxième code d'impression
print(sorted(user, key= lambda y: y["age"]))
Résultat:
[{'name': 'Abdullah', 'age': 22},
{'name': 'Citrus', 'age': 33},
{'name': 'Ben', 'age': 44},
{'name': 'Dough', 'age': 55}]
trie par âge, et donc la liste revient par ordre croissant d'âge.
Essayez ce code pour une meilleure compréhension.
def
.