PorównaniePorównania

map() vs list comprehension

map() wywołuje funkcję dla każdego elementu i zwraca leniwy iterator, a wyrażenie listowe buduje nową listę od razu i umie filtrować elementy warunkiem if.

Na tej stronie

Porównanie w tabeli

#

Przykład

#
Python
values = ["12", "7", "30"]

doubled_map = list(map(lambda v: int(v) * 2, values))
doubled_comprehension = [int(v) * 2 for v in values]

print(doubled_map)
print(doubled_comprehension)
print(doubled_map == doubled_comprehension)
Wynikzapisany wynik, możesz go sprawdzić
[24, 14, 60]
[24, 14, 60]
True

Definicja i zastosowanie

#

Obie przekształcają kolekcję element po elemencie, dając nowy ciąg wartości tej samej długości, o ile nie filtrujesz. W obu przypadkach oryginalna kolekcja się nie zmienia.

Różnią się składnią i tym, kiedy powstają wyniki. map(funkcja, kolekcja) potrzebuje już istniejącej funkcji albo lambdy i zwraca iterator: wartości powstają leniwie, dopiero gdy o nie poprosisz, np. w list() albo pętli for, i da się po nim przejść tylko raz. Wyrażenie listowe ([wyrazenie for x in kolekcja]) od razu tworzy całą listę w pamięci, a opcjonalny warunek if na końcu filtruje elementy bez dodatkowego wywołania filter().

Gdy masz już nazwaną funkcję i potrzebujesz leniwego iteratora, np. do dalszego łączenia z innymi iteratorami, map() bywa wygodny. W większości kodu czytelniejsze jest wyrażenie listowe, zwłaszcza gdy przekształcenie jest krótkie albo trzeba dodać warunek. Wersja z nawiasami okrągłymi, czyli wyrażenie generatorowe, daje taką samą leniwość jak map().

Składnia

#
Składnia
map(funkcja, iterable)
[wyrazenie for element in iterable if warunek]

Więcej przykładów

#
map() jest leniwy, trzeba go zamienić na listę
Python
numbers = [1, 2, 3]
result = map(lambda n: n * n, numbers)

print(type(result).__name__)
print(list(result))
print(list(result))
Wynikzapisany wynik, możesz go sprawdzić
map
[1, 4, 9]
[]

Iterator zużywa się po pierwszym przejściu. Druga próba zamiany na listę daje już pustą listę.

Tylko wyrażenie listowe filtruje bez filter()
Python
scores = [45, 82, 67, 91, 30]

passed_comprehension = [s for s in scores if s >= 60]
passed_map_filter = list(filter(lambda s: s >= 60, map(lambda s: s, scores)))

print(passed_comprehension)
print(passed_comprehension == passed_map_filter)
Wynikzapisany wynik, możesz go sprawdzić
[82, 67, 91]
True

Dobre praktyki

#
  • Potrzebujesz tylko przekształcenia bez warunku? Obie opcje działają, ale wyrażenie listowe zwykle łatwiej czyta się w Pythonie.
  • Gdy trzeba przefiltrować i przekształcić naraz, wyrażenie listowe z if jest krótsze niż łączenie map() i filter().
  • Jeśli dane są bardzo duże i chcesz przetwarzać je leniwie bez tworzenia listy, użyj map() albo wyrażenia generatorowego (wyrazenie for x in kolekcja).

Powiązane hasła

#

Widzisz błąd albo brakuje przykładu? Napisz do nas.