filter
, map
i reduce
działają doskonale w Pythonie 2. Oto przykład:
>>> def f(x):
return x % 2 != 0 and x % 3 != 0
>>> filter(f, range(2, 25))
[5, 7, 11, 13, 17, 19, 23]
>>> def cube(x):
return x*x*x
>>> map(cube, range(1, 11))
[1, 8, 27, 64, 125, 216, 343, 512, 729, 1000]
>>> def add(x,y):
return x+y
>>> reduce(add, range(1, 11))
55
Ale w Python 3 otrzymuję następujące dane wyjściowe:
>>> filter(f, range(2, 25))
<filter object at 0x0000000002C14908>
>>> map(cube, range(1, 11))
<map object at 0x0000000002C82B70>
>>> reduce(add, range(1, 11))
Traceback (most recent call last):
File "<pyshell#8>", line 1, in <module>
reduce(add, range(1, 11))
NameError: name 'reduce' is not defined
Byłbym wdzięczny, gdyby ktoś mógł mi wyjaśnić, dlaczego tak jest.
Zrzut ekranu kodu dla większej przejrzystości:
python
python-3.x
filter
functional-programming
reduce
Dick Lucas
źródło
źródło
Odpowiedzi:
Możesz przeczytać o zmianach w Co nowego w Python 3.0 . Powinieneś przeczytać go dokładnie, kiedy przechodzisz z wersji 2.x na 3.x, ponieważ wiele zostało zmienionych.
Cała odpowiedź tutaj to cytaty z dokumentacji.
Widoki i iteratory zamiast list
Wbudowane
źródło
list(map(...)
wszędzie ... jak na świecie pomaga czytelność ...python
nie może poradzić sobie z progresywną / streamingową aplikacją funkcjonalnych kombinacji. Inne języki Mogę połączyć kilkanaście operacji z kolekcją z rzędu i jest to czytelne. Tutaj? co chcesz - kilkanaście sposobów zagnieżdżonychin
?list
w ogóle musisz dodać połączenie? Pomyślałem, że znaczenie „streaming” jest takie, że „żadna lista nie jest tworzona; przed przejściem do następnego przetworz każdy element wejścia całkowicie”.map
.Funkcjonalność
map
ifilter
została celowo zmieniona, aby zwrócić iteratory, a redukcja została usunięta z wbudowanego i umieszczona wfunctools.reduce
.Tak więc, na
filter
imap
, można owinąć jelist()
, aby zobaczyć wyniki jak przedtem.Zaleca się teraz, aby zastąpić korzystanie z mapy i filtru wyrażeniami generatora lub listami. Przykład:
Mówi się, że dla pętli 99% czasu jest łatwiejszych do odczytania niż zmniejszania, ale po prostu bym się trzymał
functools.reduce
.Edycja : Liczba 99 procent jest pobierana bezpośrednio ze strony What's New In Python 3.0 autorstwa Guido van Rossuma.
źródło
[i*i*i for i in range(1,11)]
i**3
zadzwonii.__pow__(3)
ii*i*i
i.__mul__(i).__mul__(i)
(lub coś takiego). Z ints to nie ma znaczenia, ale z liczbami liczbowymi / niestandardowymi klasami może nawet dawać różne wyniki.list(list(list(.. )))
robić to, co było już pełne w Pythonie.Jako dodatek do innych odpowiedzi brzmi to jak dobry przypadek użycia dla menedżera kontekstu, który odwzoruje nazwy tych funkcji na te, które zwracają listę i wprowadzają
reduce
w globalnej przestrzeni nazw.Szybka implementacja może wyglądać następująco:
Przy użyciu, które wygląda tak:
Które wydruki:
Tylko moje 2 centy :-)
źródło
python
jako język jest bałagan - ale ma v dobre i bardzo dobre biblioteki:numpy
,pandas
,statsmodels
i przyjaciół .. I zostały buliding bibliotek wygodę jak pokazać tutaj, aby zmniejszyć ból w języku ojczystym - ale straciły energię, a nie próbować zboczyć daleko oddata.frame
/datatable
lubxarray
. Ale chwała za próbę ...Ponieważ
reduce
metoda została usunięta z wbudowanej funkcji z Python3, nie zapomnij zaimportować dofunctools
swojego kodu. Zobacz fragment kodu poniżej.źródło
Oto przykłady funkcji Filtruj, mapuj i zmniejszaj.
//Filtr
//Mapa
//Redukować
Funkcja zmniejszania, ponieważ nie jest powszechnie używana, została usunięta z wbudowanych funkcji w Pythonie 3. Jest ona nadal dostępna w module funkools, więc możesz:
źródło
Jedną z zalet mapowania, filtrowania i zmniejszania jest to, jak stają się one czytelne, gdy „połączymy” je razem, aby zrobić coś złożonego. Jednak wbudowana składnia nie jest czytelna i jest „wsteczna”. Sugeruję więc użycie
PyFunctional
pakietu ( https://pypi.org/project/PyFunctional/ ). Oto porównanie tych dwóch:Wersja PyFunkcjonalna
Bardzo czytelna składnia. Możesz powiedzieć:
Domyślna wersja Python
To wszystko do tyłu. Musisz powiedzieć:
źródło