2012-06-11 12 views
185
map(function, iterable, ...) 

Zastosuj funkcję do każdej pozycji z iteracji i zwróć listę wyników. Jeśli przekazywane są dodatkowe iterowalne argumenty, funkcja musi przyjmować wiele argumentów i jest stosowana równolegle do elementów ze wszystkich iteracji.Opis funkcji mapy

Jeśli jedna iteracja jest krótsza od innej, zakłada się, że jest ona uzupełniona o Brak pozycji.

Jeśli funkcja ma wartość None, przyjęto funkcję identyfikacji; jeśli istnieje wiele argumentów, map() zwraca listę składającą się z krotek zawierających odpowiednie pozycje ze wszystkich iterables (rodzaj operacji transpozycji).

Iterowalne argumenty mogą być sekwencją lub dowolnym obiektem iterowanym; wynikiem jest zawsze lista.

Jaką rolę odgrywa to w tworzeniu produktu kartezjańskiego?

content = map(tuple, array) 

Jaki wpływ ma umieszczenie krotki w dowolnym miejscu? Zauważyłem również, że bez funkcji mapowej wyjście to , a wraz z nim a, b, c.

Chcę w pełni zrozumieć tę funkcję. Definicje referencyjne również są trudne do zrozumienia. Za dużo fantazyjnego puchu.

+1

Co właściwie chcesz osiągnąć i dlaczego konkretnie chcesz użyć 'map'? –

+0

więc mapa po prostu stosuje się do każdego elementu? –

+3

@WebMaster tak, zgodnie z pierwszym zdaniem wklejonej dokumentacji - "Zastosuj funkcję do każdej pozycji z iteracją". Reszta paragrafu dotyczy bardziej złożonych przypadków - na przykład 'map (None, a, b, c)' okazuje się robić 'zip (a, b, c)'. Ale bardzo rzadko zdarza się to w praktyce, właśnie dlatego, że wywołanie "zip" jest równoważne. – lvc

Odpowiedz

271

map nie jest szczególnie pythonic. Polecam przy użyciu wyrażeń listowych zamiast:

map(f, iterable) 

jest w zasadzie równoważne:

[f(x) for x in iterable] 

map na własnych nie można zrobić produkt kartezjański, ponieważ długość swojej liście wyjścia jest zawsze taka sama jako listę wejściową. Można trywialnie zrobić kartezjański produkt z listy pojmowania choć:

[(a, b) for a in iterable_a for b in iterable_b] 

Składnia jest trochę mylące - to w zasadzie równoważne:

result = [] 
for a in iterable_a: 
    for b in iterable_b: 
     result.append((a, b)) 
+5

Uważam, że używanie 'map' jest dużo mniej szczegółowe niż rozumienie list, przynajmniej dla przypadku, który demonstrujesz. – marbel

+1

Jak korzystać z mapy do właściwości? Jaki jest odpowiednik 'mapy'' [v .__ name__ dla v in (object, str)]? –

+0

@ASz Co powiesz na 'map (lambda v: v .__ name__, list)'? –

64

w ogóle nie dotyczy produktu kartezjańskiego, chociaż wyobrażam sobie, że ktoś dobrze zorientowany w programowaniu funkcjonalnym mógłby wymyślić jakiś niemożliwy do zrozumienia sposób generowania jednego przy użyciu map.

map w Pythonie 3 jest równoważna to:

def map(func, iterable): 
    for i in iterable: 
     yield func(i) 

a jedyną różnicą w Pythonie 2 jest to, że będzie budować pełną listę wyników powrót wszystko naraz zamiast yield inż.

Choć konwencja Python zazwyczaj preferuje listowe (lub wyrażeń generatora), aby osiągnąć ten sam wynik jako wezwanie do map, szczególnie jeśli używasz wyrażenia lambda jako pierwszy argument:

[func(i) for i in iterable] 

Jako przykład tego, o co prosiłeś w komentarzach do pytania - "zmień ciąg w tablicę", przez "tablicę" prawdopodobnie chcesz albo krotkę albo listę (oba zachowują się trochę jak tablice z innych języków) -

>>> a = "hello, world" 
>>> list(a) 
['h', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd'] 
>>> tuple(a) 
('h', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd') 

Zastosowanie map tutaj będzie, jeśli zaczniesz z listy ciągów zamiast pojedynczego sznurka - map może listify wszystkie z nich z osobna:

>>> a = ["foo", "bar", "baz"] 
>>> list(map(list, a)) 
[['f', 'o', 'o'], ['b', 'a', 'r'], ['b', 'a', 'z']] 

Zauważ, że map(list, a) jest równoważne w Pythonie 2, ale w Python 3 potrzebujesz wywołania list, jeśli chcesz zrobić coś innego niż wprowadzić go do pętli for (lub funkcji przetwarzania, takiej jak sum, która potrzebuje tylko wersji iterowalnej, a nie sekwencji).Ale również pamiętać jeszcze, że lista rozumienie jest zazwyczaj preferowane:

>>> [list(b) for b in a] 
[['f', 'o', 'o'], ['b', 'a', 'r'], ['b', 'a', 'z']] 
+0

map (fun x -> (x, x)) nie wydaje się trudne do zrozumienia ... (choć uzyskanie prawdziwego kartezjańskiego produktu poza mapą byłoby niemożliwe, wszystko, co mapa produkuje jest zawsze jakąś formą listy) –

22

map tworzy nową listę przez zastosowanie funkcji do każdego elementu źródła:

xs = [1, 2, 3] 

# all of those are equivalent — the output is [2, 4, 6] 
# 1. map 
ys = map(lambda x: x * 2, xs) 
# 2. list comprehension 
ys = [x * 2 for x in xs] 
# 3. explicit loop 
ys = [] 
for x in xs: 
    ys.append(x * 2) 

n-ary map jest odpowiednikiem skompresowanie wprowadź iterables razem, a następnie zastosuj funkcję transformacji do każdego elementu tej pośredniej listy zip. To nie produkt kartezjański:

xs = [1, 2, 3] 
ys = [2, 4, 6] 

def f(x, y): 
    return (x * 2, y // 2) 

# output: [(2, 1), (4, 2), (6, 3)] 
# 1. map 
zs = map(f, xs, ys) 
# 2. list comp 
zs = [f(x, y) for x, y in zip(xs, ys)] 
# 3. explicit loop 
zs = [] 
for x, y in zip(xs, ys): 
    zs.append(f(x, y)) 

Użyłem zip tutaj, ale map zachowanie rzeczywiście różni się nieznacznie, gdy iterables nie są tej samej wielkości - jak zauważono w jego dokumentacji, rozciąga iterables zawierać None.

+0

skomplikowane , próbując przetrawić ten post –

+1

@WebMaster Co jest w tym skomplikowanego? –

+0

Najlepsza odpowiedź w mojej opinii. Użycie lambda w przykładzie jako funkcji sprawia, że ​​jest to bardzo jasne. – sheldonzy

17

Upraszczając nieco, można sobie wyobrazić map() robi coś tak:

def mymap(func, lst): 
    result = [] 
    for e in lst: 
     result.append(func(e)) 
    return result 

jak widać, potrzeba funkcję oraz listę i zwraca nową listę z wynikiem zastosowania funkcji do każdego z elementy na liście wejściowej. I powiedział: „upraszczając trochę”, bo w rzeczywistości map() może przetwarzać więcej niż jeden iterable:

Jeśli dodatkowe iterowalny argumenty są przekazywane, funkcja musi przyjąć, że wiele argumentów i jest stosowana do elementów ze wszystkich iterables równolegle . Jeśli jeden iterowalny jest krótszy niż inny, zakłada się, że został rozszerzony o Brak elementów.

Druga część pytania: Jaką rolę odgrywa to w tworzeniu produktu kartezjańskiego? dobrze, map()mogłyby być wykorzystywane do generowania iloczyn kartezjański listy tak:

lst = [1, 2, 3, 4, 5] 

from operator import add 
reduce(add, map(lambda i: map(lambda j: (i, j), lst), lst)) 

...Ale prawdę mówiąc, używając product() jest znacznie prostszy i naturalny sposób na rozwiązanie problemu:

from itertools import product 
list(product(lst, lst)) 

Tak czy inaczej, wynik jest iloczyn kartezjański lst jak zdefiniowano powyżej:

[(1, 1), (1, 2), (1, 3), (1, 4), (1, 5), 
(2, 1), (2, 2), (2, 3), (2, 4), (2, 5), 
(3, 1), (3, 2), (3, 3), (3, 4), (3, 5), 
(4, 1), (4, 2), (4, 3), (4, 4), (4, 5), 
(5, 1), (5, 2), (5, 3), (5, 4), (5, 5)] 
6

Nadziei to pomaga komuś, że jest nowy w programowaniu i Python:

funkcja map() jest tam, aby zastosować tę samą procedurę, aby każdy item w iterable data structure, jak lists, generators, strings i inne rzeczy.

Spójrzmy na przykład: map() może iterate nad każdym item w list i zastosować function każdemu item, niż to będzie return (oddać) z new list.

Pomyśl, że masz function, który ma numer (integer), dodaje 1 do tego numeru i zwraca go.

def add_one(num): 
    new_num = num + 1 
    return new_num 

również mieć list liczb (integers)

my_list = [1,3,6,7,8,10] 

jeśli chcesz increment każdy numer (integer) w list, można wykonać następujące czynności:

map(add_one, my_list) 

Uwaga: co najmniej map() potrzebuje dwóch arguments. Najpierw nazwa function i druga nazwa podobna do list.

wynikiem powyższym przykładzie map() daje z powrotem w tym:

[2, 4, 7, 8, 9, 11] 

Pozwala zobaczyć kilka innych fajnych rzeczy map() może zrobić. map() może przyjmować wiele iterables (lists, strings, etc) i przekazywać element z każdego (używam listy jako przykładu) do function jako argument.

Mamy następujący list:

list_one = [1, 2, 3, 4, 5] 
list_two = [11, 12, 13, 14, 15] 
list_three = [21, 22, 23, 24, 25] 

map() może doprowadzić do new list która posiada dodawanie elementów w określonym index (pozycja).

Teraz pamiętaj, map(), potrzebuje function.

def add_from_three_lists(num1, num2, num3): 
    total_num = num1 + num2 + num3 
    return total_num 

teraz umożliwia korzystanie map() funkcja

map(add_from_three_lists, list_one, List_two, list_three) 

a dostaniesz:

[33, 36, 39, 42, 45] 

PAMIĘTAJ:
W python2 map(), będzie iterate (przejść pierwiastków z lists) accordi do najdłuższego numeru list, i przeprowadź NoneType do funkcji dla krótszego lists, aby Twój function szukał NoneType i obsługiwał je, w przeciwnym razie otrzymasz errors. W python 3 map() będzie działać tylko zgodnie z najkrótszym list. Ponadto w Pythonie 3, map() zwraca iterator, a nie listę.