2016-02-18 15 views
23

Załóżmy, że istnieje lista a = [1, 3, 5, 6, 8].Czy mogę korzystać z informacji indeksu w funkcji mapy?

Chcę zastosować transformację na tej liście i chcę uniknąć robienia tego sekwencyjnie, więc coś takiego jak map(someTransformationFunction, a) normalnie by załatwiło sprawę, ale co, jeśli transformacja musi mieć wiedzę o indeksie każdego obiektu?

Na przykład powiedzmy, że każdy element musi być pomnożony przez jego pozycję. Tak więc lista powinna zostać przekształcona na a = [0, 3, 10, 18, 32].

Czy jest jakiś sposób na zrobienie tego?

+0

Dobre pytanie. Spodziewam się odpowiedzi, która przechodzi dokładnie tę listę samodzielnie .. –

+0

@AvinashRaj: dlaczego to by było? Jeśli chcesz mieć indeks dla każdej wartości, podaj indeks. Jest to o wiele bardziej wydajne niż próba określenia indeksu po nim, a dla zduplikowanych wartości nawet niemożliwe. –

Odpowiedz

37

Użyj funkcji enumerate() dodać indeksach:

map(function, enumerate(a)) 

Twoja funkcja zostanie przekazany do krotki, z (index, value). W Pythonie 2, można określić, że Python rozpakowania krotki dla Ciebie w podpisie funkcji:

map(lambda (i, el): i * el, enumerate(a)) 

Zanotować (i, el) krotka w specyfikacji argumentów lambda. Można zrobić to samo w def stwierdzeniem:

def mapfunction((i, el)): 
    return i * el 

map(mapfunction, enumerate(a)) 

aby zrobić miejsce dla innych funkcji, takich jak funkcja podpis adnotacji, krotka rozpakowaniu w argumentach funkcji została usunięta z Pythona 3.

Demo:

>>> a = [1, 3, 5, 6, 8] 
>>> def mapfunction((i, el)): 
...  return i * el 
... 
>>> map(lambda (i, el): i * el, enumerate(a)) 
[0, 3, 10, 18, 32] 
>>> map(mapfunction, enumerate(a)) 
[0, 3, 10, 18, 32] 
+1

+1 dla podświetlenia podstępu z przypisaniem krotki w definicji funkcji. Nigdy wcześniej tego nie widziałem. – kwinkunks

+0

Więc ten przykład dotyczy tylko python2? – LetsPlayYahtzee

+4

@LetsPlayYahtzee: Tak, w Pythonie 3 użyj jednego argumentu (który będzie krotką); 'lambda i_el: i_el [0] * i_el [1]'; w instrukcji 'def' możesz rozpakować ją w osobnym wierszu; 'def mapfunction (i_el):', * newline-and-indent-more *, 'i, el = i_el', * newline, dopasowanie wcięcia *,' return i * el'. –

10

Można użyć enumerate():

a = [1, 3, 5, 6, 8] 

answer = map(lambda (idx, value): idx*value, enumerate(a)) 
print(answer) 

Wyjście

[0, 3, 10, 18, 32] 
6

Aby przedłużyć doskonałą odpowiedź Martijn Pieters', można również używać w połączeniu z list comprehensionsenumerate:

>>> a = [1, 3, 5, 6, 8] 
>>> [i * v for i, v in enumerate(a)] 
[0, 3, 10, 18, 32] 

lub

[mapfunction(i, v) for i, v in enumerate(a)] 

czuję listowych często są bardziej czytelne niż map/lambda konstruktów. Podczas używania nazwanej funkcji mapującej, która akceptuje bezpośrednio tupot (i, v), prawdopodobnie wygrywa map.

+0

masz rację, w późniejszym przypadku notacja 'map' ma więcej sensu. W moim przypadku użycie nazwanej funkcji z mapą było właściwym wyborem, ponieważ praktycznie funkcja musiała zrobić trochę więcej niż tylko pomnożenie przez indeks. – LetsPlayYahtzee