Kod jednowierszowy przy użyciu mapy, lambda i warunku if

Nov 22 2020

Używając funkcji zip i list, utwórz nową listę L3, która zsumuje dwie liczby, jeśli liczba z L1 jest większa niż 10, a liczba z L2 jest mniejsza niż 5. Można to zrobić w jednej linii kodu.

Wypróbowałem poniższe kody. Czy ktoś może wyjaśnić, dlaczego Python narzeka?

L1 = [1, 5, 2, 16, 32, 3, 54, 8, 100]
L2 = [1, 3, 10, 2, 42, 2, 3, 4, 3]
L3 = map(lambda  (x1,x2): x1 + x2  if(x1 > 10 and x2 < 5)  , zip(L1,L2))
L4 = map(lambda  x: x[0] + x[1]  if(x[0] > 10 and x[1] < 5)  , zip(L1,L2))
print(L3)
print(L4)

Odpowiedzi

BenB Nov 22 2020 at 03:05

Spójrz tutaj : funkcja lambda musi mieć wartość zwracaną, a jeśli twoja instrukcja if nie jest prawdziwa, nie ma jej. Dlatego musiałbyś dodać inną instrukcję, na przykład:

L4 = map(lambda  x: x[0] + x[1]  if (x[0] > 10 and x[1] < 5) else 0, zip(L1,L2))

Prowadzi do

[0, 0, 0, 18, 0, 0, 57, 0, 103]

Twoja pierwsza próba (L3) nie działa, ponieważ lambda nie może już rozpakowywać krotek w Pythonie 3.x (patrz: tutaj )

Należy również pamiętać, że map () zwraca obiekt i aby wydrukować jego zawartość, musiałbyś wywołać

print(list(map_object))
# in your case:
print(list(L4))
# or set()

Edycja na podstawie komentarza: jeśli naprawdę potrzebujesz jednowierszowego tekstu i jak w pierwszym zdaniu jest napisane „używanie funkcji zip i list”, a chcesz pominąć 0, może to zadziałać i jest łatwiejsze niż map i lambda:

L3 = [x[0]+x[1] for x in zip(L1,L2) if (x[0] > 10 and x[1] < 5)]

Edytuj 2, jeśli naprawdę, naprawdę, naprawdę nalegasz na użycie mapy i lambdy:

L4 = map(lambda  x: x[0] + x[1], filter(lambda x: (x[0] > 10 and x[1] < 5), zip(L1,L2)))
2 wjandrea Nov 22 2020 at 03:42

To jest problem XY . Używasz mapy, gdy prosi o zrozumienie listy. Zasadniczo prosi o filtr, a nie mapę.

>>> [x1+x2 for x1, x2 in zip(L1, L2) if x1>10 and x2<5]
[18, 57, 103]

Można to zrobić w funkcjonalnym stylu, ale jest takie brzydkie. Nie rób tego.

L3 = list(map(
    lambda t: t[0]+t[1],
    filter(
        lambda t: t[0]>10 and t[1]<5,
        zip(L1, L2)
        )
    ))
print(L3)  # -> [18, 57, 103]