157 votes

Est-il possible d'avoir plusieurs déclarations dans une expression lambda en python?

Je suis un débutant en python en essayant d'atteindre les objectifs suivants:

J'ai une liste de listes:

lst = [[567,345,234],[253,465,756, 2345],[333,777,111, 555]]

Je veux une carte lst dans une autre liste contenant seulement le deuxième plus petit nombre de chaque sous-liste. Donc, le résultat devrait être:

[345, 465, 333]

Par exemple, si j'étais juste intéressé par le plus petit nombre, j'ai pu faire:

map(lambda x: min(x),lst)

Je souhaite que je pourrais faire ceci:

map(lambda x: sort(x)[1],lst)

mais le tri n'est pas de la chaîne. (retourne Aucun)

il n'est ni quelque chose comme cela a permis:

map(lambda x: sort(x); x[1],lst) #hence the multiple statement question

Est-il un moyen de le faire avec la carte en python, mais sans définir une fonction nommée? (c'est facile avec des blocs anonymes en ruby, par exemple)

168voto

Brian Points 48423

Il y a différentes réponses que je peux donner ici, à partir de votre question spécifique à des préoccupations plus générales. donc, à partir de la plus spécifique à la plus générale:

Q. Pouvez-vous mettre plusieurs instructions dans un lambda?

A. No. Mais vous n'avez pas réellement besoin d'un lambda. Vous pouvez mettre les états en def à la place. c'est à dire:

def second_lowest(l):
    l.sort()
    return l[1]

map(second_lowest, lst)

Q. Pouvez-vous obtenir le deuxième plus petit élément d'une lambda par tri de la liste?

A. Oui. Comme alex réponse poinst de sortir, sorted() est une version de tri qui crée une nouvelle liste, plutôt que de tri en place, et peuvent être enchaînés. Notez que c'est probablement ce que vous devriez être à l'aide - c'est une mauvaise pratique pour votre carte pour avoir des effets secondaires sur la liste d'origine.

Q. Comment dois-je obtenir le deuxième plus petit élément de chaque liste dans une séquence de listes.

A. sorted(l)[1] n'est pas vraiment le meilleur moyen pour cela. Il a O(N log(N)) complexité, tout en O(n) solution existe. Cela peut être trouvé dans la heapq module.

>>> import  heapq
>>> l = [5,2,6,8,3,5]
>>> heapq.nsmallest(l, 2)
[2, 3]

Utilisez donc:

map(lambda x: heapq.nsmallest(x,2)[1],  list_of_lists)

Il est aussi généralement considéré comme plus clair d'utiliser une compréhension de liste, ce qui évite le lambda en tout:

[heapq.nsmallest(x,2)[1] for x in list_of_lists]

106voto

jmkg Points 98

Mettre les déclarations dans une liste peut simuler plusieurs déclarations:

Par exemple:

 lambda x: [f1(x), f2(x), f3(x), x+1]
 

37voto

2rs2ts Points 3310

Voyageur du temps ici. Si vous voulez avoir plusieurs instructions dans une lambda, vous pouvez passer d'autres lambdas comme arguments que la lambda.

(lambda x, f: list((y[1] for y in f(x))))(lst, lambda x: (sorted(y) for y in x))

Vous ne pouvez pas avoir plusieurs états, mais vous pouvez simuler en passant lambdas pour les lambdas.

Edit: Le voyageur du temps est de retour! Vous pouvez aussi abuser le comportement des expressions booléennes (en gardant à l'esprit de court-circuit des règles et des truthiness) pour les opérations de la chaîne. Utilisation de l'opérateur ternaire vous donne encore plus de puissance. Encore une fois, vous ne pouvez pas avoir plusieurs états, mais vous pouvez bien sûr avoir de nombreux appels de fonction. Cet exemple ne arbitraire indésirable avec un tas de données, mais il montre que vous pouvez faire des trucs drôles. Les instructions d'impression, sont des exemples de fonctions qui retournent None (comme l' .sort() méthode), mais ils aident aussi montrer ce que l' lambda est en train de faire.

>>> (lambda x: print(x) or x+1)(10)
10
11
>>> f = (lambda x: x[::2] if print(x) or x.sort() else print(enumerate(x[::-1]) if print(x) else filter(lambda (i, y): print((i, y)) or (i % 3 and y % 2), enumerate(x[::-1]))))
>>> from random import shuffle
>>> l = list(range(100))
>>> shuffle(l)
>>> f(l)
[84, 58, 7, 99, 17, 14, 60, 35, 12, 56, 26, 48, 55, 40, 28, 52, 31, 39, 43, 96, 64, 63, 54, 37, 79, 25, 46, 72, 10, 59, 24, 68, 23, 13, 34, 41, 94, 29, 62, 2, 50, 32, 11, 97, 98, 3, 70, 93, 1, 36, 87, 47, 20, 73, 45, 0, 65, 57, 6, 76, 16, 85, 95, 61, 4, 77, 21, 81, 82, 30, 53, 51, 42, 67, 74, 8, 15, 83, 5, 9, 78, 66, 44, 27, 19, 91, 90, 18, 49, 86, 22, 75, 71, 88, 92, 33, 89, 69, 80, 38]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99]
(0, 99)
(1, 98)
(2, 97)
(3, 96)
(4, 95)
(5, 94)
(6, 93)
(7, 92)
(8, 91)
(9, 90)
(10, 89)
(11, 88)
(12, 87)
(13, 86)
(14, 85)
(15, 84)
(16, 83)
(17, 82)
(18, 81)
(19, 80)
(20, 79)
(21, 78)
(22, 77)
(23, 76)
(24, 75)
(25, 74)
(26, 73)
(27, 72)
(28, 71)
(29, 70)
(30, 69)
(31, 68)
(32, 67)
(33, 66)
(34, 65)
(35, 64)
(36, 63)
(37, 62)
(38, 61)
(39, 60)
(40, 59)
(41, 58)
(42, 57)
(43, 56)
(44, 55)
(45, 54)
(46, 53)
(47, 52)
(48, 51)
(49, 50)
(50, 49)
(51, 48)
(52, 47)
(53, 46)
(54, 45)
(55, 44)
(56, 43)
(57, 42)
(58, 41)
(59, 40)
(60, 39)
(61, 38)
(62, 37)
(63, 36)
(64, 35)
(65, 34)
(66, 33)
(67, 32)
(68, 31)
(69, 30)
(70, 29)
(71, 28)
(72, 27)
(73, 26)
(74, 25)
(75, 24)
(76, 23)
(77, 22)
(78, 21)
(79, 20)
(80, 19)
(81, 18)
(82, 17)
(83, 16)
(84, 15)
(85, 14)
(86, 13)
(87, 12)
(88, 11)
(89, 10)
(90, 9)
(91, 8)
(92, 7)
(93, 6)
(94, 5)
(95, 4)
(96, 3)
(97, 2)
(98, 1)
(99, 0)
[(2, 97), (4, 95), (8, 91), (10, 89), (14, 85), (16, 83), (20, 79), (22, 77), (26, 73), (28, 71), (32, 67), (34, 65), (38, 61), (40, 59), (44, 55), (46, 53), (50, 49), (52, 47), (56, 43), (58, 41), (62, 37), (64, 35), (68, 31), (70, 29), (74, 25), (76, 23), (80, 19), (82, 17), (86, 13), (88, 11), (92, 7), (94, 5), (98, 1)]

7voto

alex vasi Points 2893

Utilisez la fonction triée , comme ceci:

 map(lambda x: sorted(x)[1],lst)
 

3voto

odwl Points 638

Ou si vous voulez éviter lambda et avoir un générateur à la place d'une liste:

(triés (col) [1] pour col en lst)

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